【问题标题】:Index of next occurring record下一个出现记录的索引
【发布时间】:2017-09-25 17:34:22
【问题描述】:

我有一个自行车轨迹的样本数据集。我的目标是计算出访问 B 站之间的平均间隔时间。

到目前为止,我已经能够简单地使用以下命令对数据集进行排序:

test[order(test$starttime, decreasing = FALSE),]

找到start_stationend_station等于B的行索引。

 which(test$start_station == 'B')
 which(test$end_station == 'B')

下一部分是我遇到麻烦的地方。为了计算自行车在 B 站之间经过的时间,我们必须在 start_station = "B"(自行车离开)和 下一个发生记录之间的 difftime() end_station= "B" , 即使记录恰好在同一行(参见第 6 行)。

使用下面的数据集,我们知道自行车在 B 站外在 7:30:0016:00:00 之间花费了 510 分钟,在 B 站外 18:00:0018:30:00 之间花费了 30 分钟,在 @987654332 之间花费了 210 分钟@和22:30:00在B站外,平均为250 minutes.

如何使用difftime() 在 R 中重现此输出?

> test
   bikeid start_station           starttime end_station             endtime
1       1             A 2017-09-25 01:00:00           B 2017-09-25 01:30:00
2       1             B 2017-09-25 07:30:00           C 2017-09-25 08:00:00
3       1             C 2017-09-25 10:00:00           A 2017-09-25 10:30:00
4       1             A 2017-09-25 13:00:00           C 2017-09-25 13:30:00
5       1             C 2017-09-25 15:30:00           B 2017-09-25 16:00:00
6       1             B 2017-09-25 18:00:00           B 2017-09-25 18:30:00
7       1             B 2017-09-25 19:00:00           A 2017-09-25 19:30:00
8       1             А 2017-09-25 20:00:00           C 2017-09-25 20:30:00
9       1             C 2017-09-25 22:00:00           B 2017-09-25 22:30:00
10      1             B 2017-09-25 23:00:00           C 2017-09-25 23:30:00

这里是示例数据:

> dput(test)
structure(list(bikeid = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), start_station = c("A", 
"B", "C", "A", "C", "B", "B", "А", "C", "B"), starttime = structure(c(1506315600, 
1506339000, 1506348000, 1506358800, 1506367800, 1506376800, 1506380400, 
1506384000, 1506391200, 1506394800), class = c("POSIXct", "POSIXt"
), tzone = ""), end_station = c("B", "C", "A", "C", "B", "B", 
"A", "C", "B", "C"), endtime = structure(c(1506317400, 1506340800, 
1506349800, 1506360600, 1506369600, 1506378600, 1506382200, 1506385800, 
1506393000, 1506396600), class = c("POSIXct", "POSIXt"), tzone = "")), .Names = c("bikeid", 
"start_station", "starttime", "end_station", "endtime"), row.names = c(NA, 
-10L), class = "data.frame")

【问题讨论】:

  • 第一步将转换为长格式,例如library(data.table); mtest = melt(setDT(test), id="bikeid", meas = patterns("_station", "time"), variable.name = "event", value.name = c("station", "time")); mtest[.(factor(1:2), c("start", "end")), on=.(event), event := i.V2]; setkey(mtest, bikeid, time),但我不确定之后的最佳方式。

标签: r dplyr data.table


【解决方案1】:

这将按照出现的顺序计算差异,但不会将其附加到data.frame

lapply(df1$starttime[df1$start_station == "B"], function(x, et) difftime(et[x < et][1], x, units = "mins"), et = df1$endtime[df1$end_station == "B"])

[[1]]
Time difference of 510 mins

[[2]]
Time difference of 30 mins

[[3]]
Time difference of 210 mins

[[4]]
Time difference of NA mins

计算平均时间:

v1 <- sapply(df1$starttime[df1$start_station == "B"], function(x, et) difftime(et[x < et][1], x, units = "mins"), et = df1$endtime[df1$end_station == "B"])
mean(v1, na.rm = TRUE)

[1] 250

【讨论】:

  • 谢谢,这个方法有效。您能简要解释一下function(x, et) 的工作原理吗?
  • lapply 允许将多个参数传递给函数。 x 的值是starttime,而et 是在函数之后定义的附加参数。这样参数只定义一次,但可以在函数中使用两次。
【解决方案2】:

另一种可能性:

library(data.table)
d <- setDT(test)[ , {
  start = starttime[start_station == "B"]
  end = endtime[end_station == "B"]
  .(start = start, end = end, duration = difftime(end, start, units = "min"))
}
, by = .(trip = cumsum(start_station == "B"))]
d
#    trip               start                 end duration
# 1:    0                <NA> 2017-09-25 01:30:00  NA mins
# 2:    1 2017-09-25 07:30:00 2017-09-25 16:00:00 510 mins
# 3:    2 2017-09-25 18:00:00 2017-09-25 18:30:00  30 mins
# 4:    3 2017-09-25 19:00:00 2017-09-25 22:30:00 210 mins
# 5:    4 2017-09-25 23:00:00                <NA>  NA mins


d[ , mean(duration, na.rm = TRUE)]
# Time difference of 250 mins

# or
d[ , mean(as.integer(duration), na.rm = TRUE)]
# [1] 250

数据按计数器分组,每次自行车从“B”(by = cumsum(start_station == "B")) 起步时,计数器就增加 1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-14
    相关资源
    最近更新 更多