按组累计总数

8
以下是数据集:

内容请自行添加。

d = data.frame(date = as.Date(as.Date('2015-01-01'):as.Date('2015-04-10'), origin = "1970-01-01"),
               group = rep(c('A','B','C','D'), 25), value = sample(1:100))
head(d)
         date group value
1: 2015-01-01     A     4
2: 2015-01-02     B    32
3: 2015-01-03     C    46
4: 2015-01-04     D    40
5: 2015-01-05     A    93
6: 2015-01-06     B    10

有没有更加优雅的方法来按组计算值的累积总和,而不是使用这个data.table的方法?

library(data.table)
setDT(d)
d.cast = dcast.data.table(d, group ~ date, value.var = 'value', fun.aggregate = sum)
c.sum = d.cast[, as.list(cumsum(unlist(.SD))), by = group]

这段代码看起来相当笨重,生成的矩阵过于平坦,需要使用dplyr::gatherreshape2::melt进行重新格式化。

那么R肯定有更好的解决方案了吧?


3
我有点困惑。您用语言描述的是“setDT(d)[,cumsum(value),by=group]”。 - Frank
2
你应该使用 set.seed() 来使示例可重现,并且还应该包括样本输入的期望输出。 - MrFlick
4个回答

10

如果您只想要每个组的累计和,则可以执行以下操作:

transform(d, new=ave(value,group,FUN=cumsum))

使用基础R。


打一个漂亮的一杆进洞,同时保留原始数据顺序 :) - geotheory

8

这应该可以正常工作。

library(dplyr)
d %>% 
  group_by(group) %>% 
  arrange(date) %>% 
  mutate(Total = cumsum(value))

这可能是最佳实践的方向。 - geotheory
Fortran更好。二进制是最佳选择。 - geotheory

4

由于这个问题标记了 data.table,所以你可能正在寻找(修改自@Frank评论的)方法。

setDT(d)[order(date), new := cumsum(value), by = group]

这将同时通过 date 重新排列数据(如果不需要,可以去掉 order(date)),并使用 := 运算符在原地更新数据集。


@akrun 我可能没有 Flick 那么受欢迎 ;) - David Arenburg
实际上,我没有添加那个标签,我认为是@Frank添加的。抱歉,我应该更早地回滚。 - geotheory
我认为你不需要 order(date)(正如你提到的那样)。 - Arun
不知道您可以将 order 用作 i 参数。+1! - MichaelChirico

0

就是这个吗?

sp <- split(d, d$group)
res <- lapply(seq_along(sp), function(i) cumsum(sp[[i]]$value))
res <- lapply(seq_along(res), function(i){
        sp[[i]]$c.sum <- res[[i]]
        sp[[i]]
    }) 
res <- do.call(rbind, res)
res

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接