按组累计求和

7
假设数据如下:
group1 group2 num
A      sg     1
A      sh     2
A      sg     4
B      at     3
B      al     7

a <- cumsum(data[,"num"]) # 1 3 7 10 17

我需要按组累加某些内容。实际上,我有多个列作为分组指标。我想要按照我定义的子组来获得累加总和。

例如:

如果我只按group1分组,则输出应为

group1 sum
A      1
A      3
A      7
B      3
B      10

如果我按照两个变量 group1,group2 进行分组,那么输出结果为:
group1 group2 sum
A      sg     1
A      sh     2
A      sg     5
B      at     3
B      al     7

10
尝试使用ave(df$num,df$group1,FUN=cumsum)来对group1进行求和,或者使用ave(df$num,df$group1,df$group2,FUN=cumsum)来对两个组进行求和。 - nicola
7
这应该是基本的按组操作。使用data.tablesetDT(data)[, cumsum(num), list(group1, group2)]或者使用dplyrdata %>% group_by(group1, group2) %>% mutate(sum=cumsum(num)) - akrun
@nicola 没有注意到 aveFUN 选项! - Lovnlust
@akrun。我之前没听说过这个包,稍后会去看一下。语法看起来有点奇怪。 - Lovnlust
@akrun,“dplyr”的名字本身就很难理解,我也没弄清楚它代表什么。 - Lovnlust
显示剩余3条评论
2个回答

9
library(data.table)

data <- data.table(group1=c('A','A','A','B','B'),sum=c(1,2,4,3,7))

data[,list(cumsum = cumsum(sum)),by=list(group1)]

6

除了使用data.table之外,基于R语言的tapply函数对这两种情况都适用:

dta <- read.table(text="
group1 group2 num
A      sg     1
A      sh     2
A      sg     4
B      at     3
B      al     7", header=TRUE)

dta$cumsum <- do.call(c, tapply(dta$num, dta$group1, FUN=cumsum))

对两个组进行累计求和需要一些重新排序:

dta <- dta[order(dta$group1, dta$group2, dta$num),]

dta$cumsum2 <- do.call(c, tapply(dta$num, 
                                 paste0(dta$group1, dta$group2), 
                                 FUN=cumsum))
dta
      group1 group2 num cumsum cumsum2
1      A     sg   1      1       1
3      A     sg   4      7       5
2      A     sh   2      3       2
5      B     al   7     10       7
4      B     at   3      3       3

如果你需要恢复原始的顺序:

dta[as.numeric(rownames(dta)),]
  group1 group2 num cumsum cumsum2
1      A     sg   1      1       1
2      A     sh   2      3       2
3      A     sg   4      7       5
4      B     at   3      3       3
5      B     al   7     10       7

不错!为了类型安全起见,我会在tapply()调用中添加simplify = FALSE - landau

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