如何使用R计算子组中的出现次数?

如何使用R计算子组中的出现次数?,r,dataframe,dplyr,R,Dataframe,Dplyr,我有以下data.frame(dput()在问题的末尾) 我的目标是创建一个data.frame,在这里我可以看到linkId上随时有多少辆车。 如果车辆在时间x处于链路上,则可从新到达时间(到达)和下到达时间(离开)得出。对于链路90上的time=12(12小时),必须计算有多少辆车的new\u arr\u time=12。总共最多有48个时间箱(如果为0,则无需设置时间箱) 所需表格应具有以下结构: linkId time count 90 0.0 3 90

我有以下
data.frame
dput()
在问题的末尾)

我的目标是创建一个
data.frame
,在这里我可以看到
linkId
上随时有多少辆车。 如果车辆在时间x处于链路上,则可从
新到达时间
(到达)和
下到达时间
(离开)得出。对于链路90上的
time=12
(12小时),必须计算有多少辆车的
new\u arr\u time=12
。总共最多有48个时间箱(如果为0,则无需设置时间箱)

所需表格应具有以下结构:

linkId  time    count
90      0.0     3
90      0.5     x
90      1.0     y
...
389     0.0     z
...
我的任务是创建一个有效的循环来执行此操作

提前谢谢你

数据:


我不明白你的意思:

让他们的新到达时间=12

但是,例如,如果我们假设使用duration(或另一个计算值)就足够了,则可以使用R base中的
aggregate
或packagedplyr进行这样的聚合,而无需任何循环:

d %>% group_by(linkId, duration) %>% summarize(count = n())
with(d, aggregate(list(count = linkId), list(linkId = linkId, duration=duration), length))
或带“基本R”(不带dplyr):


我希望我现在能更好地理解它,下面是一种基于
outer
产品的方法,该方法使用包tidyr处理数据。它比循环占用更多内存,但也更紧凑:


library("tidyr")
library("dplyr")

## half hour time slots
tm <- seq(0, 24, 0.5)

## Test if a value is in the interval. Please check manually with some examples.
## second version is more robust against IEEE floating point deviations
# fun <- function(i, x) (d[i, "new_arr_time"] <= x) & (x <= d[i, "dep_time"])
fun <- function(i, x) (d[i, "new_arr_time"] - x < 1e-6) & (x - d[i, "dep_time"] < 1e-6)

## outer creates all combinations between LinkIDs and time slots
expanded <- data.frame(outer(1:nrow(d), tm, fun))
names(expanded) <- tm

cbind(linkId=d$linkId, expanded) %>%
  pivot_longer(-linkId, names_to = "time", values_to = "count") %>%
  group_by(linkId, time) %>%
  summarize(count = sum(count))

图书馆(“tidyr”)
图书馆(“dplyr”)
##半小时时段

tm我的意思是,在这个例子中,到达时间必须在12点之前,离开时间必须在12点之后。谢谢你的例子。我相信,尽管它没有达到预期的效果。我必须知道在一个链接的特定时间有多少辆车。你的代码告诉我在一个链接上有多少个站点停留了多长时间,但不知道它们是否同时存在。为什么我想知道你说的“30分钟时间段”和“12”是什么意思。是晚些时候吗?是否有(有限的)一套“垃圾箱”?48?我把它改成了每小时一次的垃圾箱,让它更容易理解。之前还不清楚。我挣扎了很长时间,直到我意识到包裹碰撞
dplyr::summary(count=sum(count))
解决了这个问题。非常感谢你的帮助!!!
with(d, aggregate(list(count = linkId), list(linkId = linkId, duration=duration), length))

library("tidyr")
library("dplyr")

## half hour time slots
tm <- seq(0, 24, 0.5)

## Test if a value is in the interval. Please check manually with some examples.
## second version is more robust against IEEE floating point deviations
# fun <- function(i, x) (d[i, "new_arr_time"] <= x) & (x <= d[i, "dep_time"])
fun <- function(i, x) (d[i, "new_arr_time"] - x < 1e-6) & (x - d[i, "dep_time"] < 1e-6)

## outer creates all combinations between LinkIDs and time slots
expanded <- data.frame(outer(1:nrow(d), tm, fun))
names(expanded) <- tm

cbind(linkId=d$linkId, expanded) %>%
  pivot_longer(-linkId, names_to = "time", values_to = "count") %>%
  group_by(linkId, time) %>%
  summarize(count = sum(count))