我目前正在尝试计算公共交通工具上下车的载客量。换句话说,我想知道,对于任何给定的站点,车上有多少人。
我使用下面的代码计算了乘客负载,但您会注意到许多负载值为负值。这是我所拥有的数据的限制。
library(tidyverse)
df = structure(list(trip = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), stop = c(1,
2, 3, 4, 5, 1, 2, 3, 4, 5), on = c(2, 0, 0, 0, 0, 3, 0, 0, 0,
1), off = c(0, 3, 0, 0, 1, 0, 0, 4, 1, 0)), class = "data.frame", row.names = c(NA,
-10L))
df = df %>%
group_by(trip) %>%
mutate(diff = on-off,
load = cumsum(diff))
为了解决这个问题,我想做出一个假设,该假设将导致负载值永远不会为负。也就是说,不可能出现下车人数多于上车人数的情况。
如果你只看第一行和第二行,你会发现有 2 个人在第 1 站上车,但有 3 个人在第 2 站下车。这导致负载为 -1,这当然是不可能的。
我尝试使用滞后负载值创建一个“调整关闭”列,如果当前下车乘客的数量会导致负载为负值,则该列将使用前一站的乘客负载:
df = df %>%
mutate(
lag_load = lag(load),
adj_off = case_when(off > lag_load ~ lag_load,
TRUE ~ off))
要实现这一点,我认为必须不断重新计算负载。
我想我可以通过使用for循环得到我想要的东西,但我正在寻找一种更有效的解决方案,因为我拥有的数据包含超过300万行,而for循环将花费很长时间。任何寻找解决方案的帮助将不胜感激!
您可以调整
cumsum
函数来忽略总和低于零的情况。所以(保留您的 load
列进行比较):
cumsumpositive <- function(x){
Reduce(\(a,b) ifelse(a+b>=0,a+b,max(a,0)) ,x,accumulate = TRUE)
}
df %>%
group_by(trip) %>%
mutate(diff = on-off,
load = cumsum(diff),
loadpositive = cumsumpositive(diff))
# Groups: trip [2]
trip stop on off diff load loadpositive
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 2 0 2 2 2
2 1 2 0 3 -3 -1 2
3 1 3 0 0 0 -1 2
4 1 4 0 0 0 -1 2
5 1 5 0 1 -1 -2 1
6 2 1 3 0 3 3 3
7 2 2 0 0 0 3 3
8 2 3 0 4 -4 -1 3
9 2 4 0 1 -1 -2 2
10 2 5 1 0 1 -1 3
这可以根据您想要处理底片的方式进行调整。