R使用dplyr的mutate计算商品连续未交付天数报错如何解决
报错原因
你的代码报错核心原因是 dplyr::mutate 为矢量化运算,会一次性计算整列结果,你在定义Delivered_Flag的逻辑中直接引用了还未创建完成的Delivered_Flag本身,自然会触发「对象未找到」的报错。
可行实现方案
你可以用purrr::accumulate实现逐行迭代的计算逻辑,完整可运行代码如下:
library(dplyr) library(purrr) # 原始构造数据 item <- c(5,5,5,5,5,5,5,5,7,7,7,7,7,7,7) Date <- c("2/02/2021","3/02/2021","4/02/2021","5/02/2021","6/02/2021","7/02/2021","8/02/2021","9/02/2021","2/02/2021","3/02/2021","4/02/2021","5/02/2021","6/02/2021","7/02/2021","8/02/2021") Delivered_QTY<- c(4,0,0,4,4,0,0,0,0,0,1,2,5,0,0) df<- data.frame(item,Date,Delivered_QTY) # 计算连续未交付天数 df <- df %>% group_by(item) %>% mutate(Delivered_Flag = accumulate(Delivered_QTY, ~if(.y == 0) .x + 1 else 0, .init = 0)[-1]) %>% ungroup()
逻辑说明
accumulate 是迭代计算函数,每一步的返回值会作为下一次迭代的输入.x,当前遍历到的Delivered_QTY值为.y:
- 若当日交付量为0,就在上一次计算结果的基础上加1
- 若当日交付量不为0,直接重置为0
.init=0是设置迭代初始值,末尾用[-1]去掉初始值对应的多余元素,保证输出长度和原数据匹配。
如果不想额外加载purrr包,也可以用基础dplyr的分组逻辑实现:
df <- df %>% group_by(item) %>% # 每次遇到交付时给新的连续未交付片段打分组id mutate(break_flag = cumsum(Delivered_QTY != 0)) %>% group_by(item, break_flag) %>% # 同一片段内行号减1即为连续未交付天数 mutate(Delivered_Flag = row_number() - 1) %>% ungroup() %>% select(-break_flag)
两种方案输出结果均和你给出的预期完全一致。
内容的提问来源于stack exchange,提问作者jontieez
相关产品推荐
相关产品推荐

