我想针对每次观察计算R的时间之间的差异,因为它与公交车的到站时间和时间表有关。我到目前为止的代码是:
for (i in ida1d$DATA_TRAMA) {
for (j in horidat$CORD4) {
if((ida1d$DATA_TRAMA - horidat$CORD4 < ida1d$diff)) {
ida1d$diff <- ida1d$DATA_TRAMA - horidat$CORD4
}
}
}
我有这些数据框:
ida1d
,其中包含我想要的具体信息horidat
,其中有时间表ida1d$DATA_TRAMA
和horidat$CORD4
均为POSIXct %Y-m%-%d %H:%M:%S
格式。现在我想做的是在ida1d表中有一列,并带有不同之处。问题在于,对于前几个观察,它可以正确计算差异,但是从某个角度来看,它不能正确计算horidat
(时间表)的观察数,而对于ida1d
,则观察数是88我认为计算的问题可能是因为此,因此尝试使用for循环来解决问题,但是我认为我缺少了一些东西...
ida1d的日期和时间是公交车全天到达公交车站的时间:
ida1d$DATA_TRAMA
[1] 2010-10-01 00:00:08
2010-10-01 00:29:45
2010-10-01 06:22:56
2010-10-01 06:38:55
2010-10-01 06:52:41
2010-10-01 07:05:08
2010-10-01 07:15:17
2010-10-01 07:25:14
2010-10-01 07:38:25
2010-10-01 07:44:55
2010-10-01 07:54:44
2010-10-01 08:05:05
2010-10-01 08:14:43
2010-10-01 08:24:11
2010-10-01 08:33:29
2010-10-01 08:46:26
2010-10-01 08:54:40
2010-10-01 09:04:34
2010-10-01 09:14:53
这是公共汽车(horidat
)的时间表
horidat$CORD4
[2] 2010-10-01 00:00:00
2010-10-01 00:30:00
2010-10-01 06:25:00
2010-10-01 06:45:00
2010-10-01 07:00:00
2010-10-01 07:15:00
2010-10-01 07:30:00
2010-10-01 07:45:00
2010-10-01 07:57:00
2010-10-01 08:09:00
2010-10-01 08:21:00
2010-10-01 08:32:00
2010-10-01 08:43:00
2010-10-01 08:54:00
2010-10-01 09:06:00
2010-10-01 09:18:00
我可以计算出[1]和[2]之间的差,正如我们在结果[3]下方看到的那样:
ida1d$diff
Time differences in secs
[3] 8
-15
-124
-365
-439
-592
-883
-1186
-1115
-1445
-1576
-1615
-1697
-1789
-1951
-1894
-2120
-2246
我们可以看到它从一开始就很好地开始,然后在其余的计算中都出错了,这就是我的问题,我想为每次观察获得列中差的最小值,也许它使用其他值,因此我猜是错误的计算...
答案 0 :(得分:2)
我要发表评论,但没有声誉。寻找几点。
看起来一个表有事件,另一个表有某种属性?如果您可以提供有关每个表格中有哪些内容的详细信息,那将会有所帮助。
无论如何,我都会大致勾勒出我将如何处理它。通常,您要避免for循环。您可以使用联接或矢量操作,它们的性能更高。该解决方案似乎将是两个数据框之间的连接,并带有一个突变来创建差异列。如果不是这种情况,请告诉我!
# install these if you don't have them
library(dplyr)
library(magrittr)
horidat %>%
xxxx_join(ida1d, on=c('some_column1','some_column2') %>%
mutate(diff = as.numeric(difftime(DATA_TRAMA, CORD4, units='secs')))
xxxx_join是适当的连接,例如left_join。
答案 1 :(得分:2)
这是使用fuzzyjoin
软件包的一种方法。使用data.table
的方法更快,例如here和here,但是对我来说,这种方法更易于遵循,并且在必要时可以更轻松地调整匹配规则。
fuzzyjoin::difference_left_join
的作用类似于基R中的merge
或left_join
中的dplyr
,在两个数据集之间创建了数据库样式的“联接”。在这种情况下,它将连接两个表中的相应时间戳。作为“左”连接,它将保留原始到达数据帧的每一行的至少一个副本,并为每个与CORD4
足够近的匹配DATA_TRAMA
计划的停靠点包括一行时间。在这种情况下,通过设置max_dist = 15*60
,我们将在到达时间的15分钟(15分钟x 60秒)内获得所有计划的停靠点。这可能比您想要的要多(41个足够接近的比赛,需要19个到达时间),但是,您可以灵活地决定将哪些预定的停靠点与实际到达时间联系起来。
在这种情况下,为了选择最接近时间的计划停靠点,我使用group_by
中的top_n
和dplyr
来保留每次到达的绝对时间差最小的行。
library(dplyr); library(fuzzyjoin)
ida1d %>%
# select() to bring in only CORD4 from horidat
difference_left_join(horidat %>% select(CORD4),
by = c(DATA_TRAMA = "CORD4"),
max_dist = 15*60, distance_col = "abs_dif") %>%
# difference_left_join based on absolute differences
# add signed difference
mutate(difference = DATA_TRAMA - CORD4) %>%
# could use filter like this to limit to only late buses:
# filter(difference >= 0) %>%
group_by(DATA_TRAMA) %>%
top_n(-1, wt = difference) %>%
ungroup()
# A tibble: 19 x 4
DATA_TRAMA CORD4 abs_dif difference
<dttm> <dttm> <time> <time>
1 2010-10-01 00:00:08 2010-10-01 00:00:00 8 secs 8 secs
2 2010-10-01 00:29:45 2010-10-01 00:30:00 15 secs -15 secs
3 2010-10-01 06:22:56 2010-10-01 06:25:00 124 secs -124 secs
4 2010-10-01 06:38:55 2010-10-01 06:45:00 365 secs -365 secs
5 2010-10-01 06:52:41 2010-10-01 07:00:00 439 secs -439 secs
6 2010-10-01 07:05:08 2010-10-01 07:00:00 308 secs 308 secs
7 2010-10-01 07:15:17 2010-10-01 07:15:00 17 secs 17 secs
8 2010-10-01 07:25:14 2010-10-01 07:30:00 286 secs -286 secs
9 2010-10-01 07:38:25 2010-10-01 07:45:00 395 secs -395 secs
10 2010-10-01 07:44:55 2010-10-01 07:45:00 5 secs -5 secs
11 2010-10-01 07:54:44 2010-10-01 07:57:00 136 secs -136 secs
12 2010-10-01 08:05:05 2010-10-01 08:09:00 235 secs -235 secs
13 2010-10-01 08:14:43 2010-10-01 08:09:00 343 secs 343 secs
14 2010-10-01 08:24:11 2010-10-01 08:21:00 191 secs 191 secs
15 2010-10-01 08:33:29 2010-10-01 08:32:00 89 secs 89 secs
16 2010-10-01 08:46:26 2010-10-01 08:43:00 206 secs 206 secs
17 2010-10-01 08:54:40 2010-10-01 08:54:00 40 secs 40 secs
18 2010-10-01 09:04:34 2010-10-01 09:06:00 86 secs -86 secs
19 2010-10-01 09:14:53 2010-10-01 09:18:00 187 secs -187 secs
样本数据:
ida1d = data.frame(DATA_TRAMA = as.POSIXct(
c(
"2010-10-01 00:00:08",
"2010-10-01 00:29:45",
"2010-10-01 06:22:56",
"2010-10-01 06:38:55",
"2010-10-01 06:52:41",
"2010-10-01 07:05:08",
"2010-10-01 07:15:17",
"2010-10-01 07:25:14",
"2010-10-01 07:38:25",
"2010-10-01 07:44:55",
"2010-10-01 07:54:44",
"2010-10-01 08:05:05",
"2010-10-01 08:14:43",
"2010-10-01 08:24:11",
"2010-10-01 08:33:29",
"2010-10-01 08:46:26",
"2010-10-01 08:54:40",
"2010-10-01 09:04:34",
"2010-10-01 09:14:53"
)
))
horidat = data.frame(CORD4 = as.POSIXct(
c(
"2010-10-01 00:00:00",
"2010-10-01 00:30:00",
"2010-10-01 06:25:00",
"2010-10-01 06:45:00",
"2010-10-01 07:00:00",
"2010-10-01 07:15:00",
"2010-10-01 07:30:00",
"2010-10-01 07:45:00",
"2010-10-01 07:57:00",
"2010-10-01 08:09:00",
"2010-10-01 08:21:00",
"2010-10-01 08:32:00",
"2010-10-01 08:43:00",
"2010-10-01 08:54:00",
"2010-10-01 09:06:00",
"2010-10-01 09:18:00"
)
))