使用R tidyverse计算非负修正载客量的高效实现方案
高效计算公共交通站点载客量(避免负值)
问题背景
用cumsum计算公交各站点载客量时,因下车人数超过当前实际载客量,出现了负值(例如站点1上2人、站点2下3人导致load=-1)。尝试用滞后载客量调整下车人数,但需要连续重算载客量,且数据量超300万行,不能用耗时的for循环。
初始代码(存在负值问题)
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))
高效解决方案(向量式操作,无for循环)
利用purrr::accumulate实现逐站累积计算,同时确保载客量不会低于0,这种方式比循环高效,适合处理百万级数据:
df_clean <- df %>% group_by(trip) %>% mutate( # 计算调整后的载客量:上一站载客量 + 当前上车 - 当前下车,结果不低于0 load = accumulate(1:n(), .init = 0, function(prev_load, idx) { max(prev_load + on[idx] - off[idx], 0) }) %>% tail(-1), # 移除初始的0,匹配数据行数 # 计算实际可下车人数:取原下车人数和上一站载客量的较小值 adj_off = pmap_dbl(list(lag(load, default = 0), off), ~ min(.y, .x)) ) %>% ungroup()
结果说明
- 对于trip1的站点2,原下车人数3超过上一站载客量2,调整后实际下车2人,载客量变为0
- 后续站点的载客量计算基于前一站的调整后数值,不会再出现负值
- 向量式操作避免了循环的性能损耗,300万行数据可快速处理
内容的提问来源于stack exchange,提问作者z_11122
相关产品推荐
相关产品推荐

