You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用dplyr引用同一列上一行计算值生成nameCntSpltGrp列?

修复dplyr中依赖上一行计算值的列生成问题

问题说明

需要在dplyr中生成nameCntSpltGrp列,计算逻辑如下:

  • 若当前行nameCntSplt > 0,取值为nameCntSplt
  • 若当前行Name与上一行Name相同,取值为上一行的nameCntSpltGrp
  • 其余情况取值为0

原代码中使用lag()无法实现需求,因为mutate里的lag()引用的是列的原始值,而非逐行计算后的实时结果。

解决方案

使用purrr::accumulate()函数逐行计算,该函数可以将上一次的计算结果传递到下一行,完美适配依赖上一行结果的场景。

完整代码

library(dplyr)
library(purrr)

myData <- 
  data.frame(
    Name = c("R","R","T","R","N","N"),
    Group = c(0,0,0,0,1,1)
  )

myDataFill <- myData %>%
  group_by(Name, Group) %>% 
  mutate(nameCnt = row_number()) %>% 
  mutate(subGrpRank = ifelse(Group > 0, row_number(), 0)) %>% 
  mutate(nameCntSplt = ifelse(subGrpRank == 1, nameCnt, 0)) %>% 
  ungroup() %>%
  mutate(nameCntSpltGrp = accumulate(
    .x = 1:n(),
    .f = function(prev_val, i) {
      if (nameCntSplt[i] > 0) {
        nameCntSplt[i]
      } else if (Name[i] == Name[i-1]) {
        prev_val
      } else {
        0
      }
    },
    .init = 0
  )[-1]) # 去掉初始值,匹配数据行数

print.data.frame(myDataFill)

代码解释

  1. accumulate()的.x参数传入行号序列1:n(),用于逐行索引数据
  2. .f定义计算逻辑:
    • 当当前行nameCntSplt大于0时,直接取该值
    • 否则判断当前行Name是否与上一行一致,一致则用上一次的计算结果prev_val
    • 其余情况返回0
  3. .init = 0设置初始值(对应第0行的虚拟值),最后用[-1]去掉这个初始值,保证结果与原数据行数匹配

运行结果

Name Group nameCnt subGrpRank nameCntSplt nameCntSpltGrp
1    R     0       1          0           0              0
2    R     0       2          0           0              0
3    T     0       1          0           0              0
4    R     0       3          0           0              0
5    N     1       1          1           1              1
6    N     1       2          2           0              1

内容的提问来源于stack exchange,提问作者Village.Idyot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:54:35