使用 R tidyverse 计算修改后的乘客负载,条件是负载不能为负数

问题描述 投票:0回答:1

我目前正在尝试计算公共交通工具上下车的载客量。换句话说,我想知道,对于任何给定的站点,车上有多少人。

我使用下面的代码计算了乘客负载,但您会注意到许多负载值为负值。这是我所拥有的数据的限制。

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循环将花费很长时间。任何寻找解决方案的帮助将不胜感激!

r dplyr
1个回答
0
投票

您可以调整

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

这可以根据您想要处理底片的方式进行调整。

© www.soinside.com 2019 - 2024. All rights reserved.