计算每行的累积总和

时间:2011-09-26 03:25:47

标签: r

我正在尝试使用以下代码计算每行的累积总和:

df <- data.frame(count=1:10)

for (loop in (1:nrow(df)))
    {df[loop,"acc_sum"] <- sum(df[1:loop,"count"])}

但是我不喜欢这里的显式循环,我该如何修改呢?

6 个答案:

答案 0 :(得分:41)

您想要cumsum()

df <- within(df, acc_sum <- cumsum(count))

答案 1 :(得分:10)

您也可以尝试mySum = t(apply(df, 1, cumsum))

转置是在那里,因为结果出来转换,原因我还没有确定。

我确信plyr有很好的解决方案,例如ddply和多核方法。

答案 2 :(得分:7)

要复制OP的结果,只需要cumsum函数,就像Chase的答案所示。但是,OP的“每行”措辞可能表示对矩阵或数据框的累积和感兴趣。

对于data.frame的逐列的cumsums,有趣的是,cumsum再一次需要! cumsum是一个原语,它是Math通用函数组的一部分,它是为数据帧定义的,它将函数应用于每一列;在代码中,它只是执行此操作:x[] <- lapply(x, .Generic, ...)

> foo <- matrix(1:6, ncol=3)
> df <- data.frame(foo)
> df
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
> cumsum(df)
  X1 X2 X3
1  1  3  5
2  3  7 11

有趣的是,sum不是Math的一部分,而是Summary通用函数组的一部分;对于数据帧,该组首先将数据帧转换为矩阵,然后调用泛型,因此sum不返回列的总和,而是总和:

> sum(df)
[1] 21

这种差异(在我看来)很可能是因为cumsum返回的尺寸与原始尺寸相同,但sum不会。

对于逐行累积和,没有一个函数可以复制我所知道的这种行为;迭代器的解决方案可能是最直接的解决方案之一。

如果速度是一个问题,那么用C语言写它几乎肯定是最快和最简单的;但是,通过使用简单的for循环,它可以为长循环加速一点(~2x?)。

rowCumSums <- function(x) {
  for(i in seq_len(dim(x)[1])) { x[i,] <- cumsum(x[i,]) }; x
}
colCumSums <- function(x) {
  for(i in seq_len(dim(x)[2])) { x[,i] <- cumsum(x[,i]) }; x
}

通过使用普通cumsum并在到达列末尾时减去总和,可以加快速度。对于行累积总和,需要转置两次。

colCumSums2 <- function(x) {
  matrix(cumsum(rbind(x,-colSums(x))), ncol=ncol(x))[1:nrow(x),]
}
rowCumSums2 <- function(x) {
  t(colCumSums2(t(x)))
}

但这真的是一个黑客。不要这样做。

答案 3 :(得分:2)

使用data.table,您也可以使用

dt <- as.data.table(df)
dt[, acc_sum := cumsum(count)]

答案 4 :(得分:0)

cumsum()的替代方法可能是:

within(df, acc_sum <- Reduce("+", count, accumulate = TRUE))

   count acc_sum
1      1       1
2      2       3
3      3       6
4      4      10
5      5      15
6      6      21
7      7      28
8      8      36
9      9      45
10    10      55

答案 5 :(得分:0)

我们可以使用

library(collapse)
dapply(df, MARGIN = 1, FUN = fcumsum)