R数据框中计算当前行前特定值出现次数及累计和的实现方法
R实现按名称分组的倒序累计计数与求和
首先给出你需要的高性能实现方案,两种实现路径可选,均为向量化运算,避免逐行遍历的性能问题,完全匹配你描述的计算逻辑:
dplyr实现方案(代码可读性更高)
# 示例数据 index <- c(8,7,6,5,4,3,2,1) names <- c("Joe", "John", "Chris", "Joe", "Al", "Fred", "Joe", "John") values <- c(1,9,2,9,1,3,3,7) df <- data.frame(index,names,values) library(dplyr) df <- df %>% group_by(names) %>% # 组内按index降序排列,保证index更大的行排在前面 arrange(desc(index), .by_group = TRUE) %>% mutate( # 行号减1即为比当前index大的同名称行数 running.count = row_number() - 1, # 累计求和减去当前值即为比当前index大的同名称values总和 running.total = cumsum(values) - values ) %>% ungroup() %>% # 恢复原数据的行顺序 arrange(index)
R基础包实现方案(无需安装第三方依赖)
index <- c(8,7,6,5,4,3,2,1) names <- c("Joe", "John", "Chris", "Joe", "Al", "Fred", "Joe", "John") values <- c(1,9,2,9,1,3,3,7) df <- data.frame(index,names,values) # 先按名称分组、index降序排序 df <- df[order(df$names, -df$index), ] # 分组计算累计计数 df$running.count <- ave(df$values, df$names, FUN = function(x) seq_along(x) - 1) # 分组计算累计求和 df$running.total <- ave(df$values, df$names, FUN = function(x) cumsum(x) - x) # 恢复原数据的index排序 df <- df[order(df$index), ]
结果验证
运行上述代码后得到的结果完全符合你的要求,你提到的第7行(index=2,名称为Joe)的running.count为2,running.total为10,和示例一致:
| index | names | values | running.count | running.total |
|---|---|---|---|---|
| 1 | John | 7 | 1 | 9 |
| 2 | Joe | 3 | 2 | 10 |
| 3 | Fred | 3 | 0 | 0 |
| 4 | Al | 1 | 0 | 0 |
| 5 | Joe | 9 | 1 | 1 |
| 6 | Chris | 2 | 0 | 0 |
| 7 | John | 9 | 0 | 0 |
| 8 | Joe | 1 | 0 | 0 |
性能说明
两种方案均采用分组向量化运算,无需逐行筛选子集,对于百万级行的数据集也能在毫秒级完成计算,远高于逐行循环的性能。
内容的提问来源于stack exchange,提问作者lschj
相关产品推荐
相关产品推荐

