按组对多个列求和

时间:2013-08-22 17:57:27

标签: r

我的数据看起来像这样:

Time ColA ColB ColC
0    1    10   5
1    3    7    15
2    0    8    9
3    3    4    5
4    4    5    6
7    10   23   4

我想将数据分组为相同大小的时间间隔,并对每列的变量求和。例如,这将是将时间分组为2的结果:

Time ColA ColB ColC
0    4    17   20
2    3    12   14
4    4    5    6
7    10   23   4

我可以通过引入一个值为floor(data$Time/2)的新列标记数据,但不清楚如何进行求和。我看过的大多数软件包似乎只汇总了一个列,而我想总结所有列。

3 个答案:

答案 0 :(得分:5)

使用“data.table”包!语法更容易,运行时间更快。

### Load package
require(data.table)

### Set up variables; Create data.table
time <- c(0:4, 7)
ColA <- c(1, 3, 0, 3, 4, 10)
ColB <- c(10, 7, 8, 4, 5, 23)
ColC <- c(5, 15, 9, 5, 6, 4)
data <- data.table(time, ColA, ColB, ColC)

### Determine which columns we want to apply the function to
sum.cols <- grep("Col", names(data), value = T)   

### Sum each column within each group
data[, lapply(.SD, sum), by = floor(time / 2), .SDcols = sum.cols]

### Output:
    floor ColA ColB ColC
1:     0    4   17   20
2:     1    3   12   14
3:     2    4    5    6
4:     3   10   23    4

请注意,符号“.SD”表示“数据子集”。在这种情况下,lapply函数迭代数据表的列,将函数“sum”应用于每列。在每列中,计算我们的“floor”变量的每个级别的总和。

答案 1 :(得分:2)

只是为了证明Ferdinand.Kraft的'重复'调用是正确的,并且可以说更接近于请求,其中包括查看原始单位中创建的区间的请求。

> aggregate(data[-1], list(cut(data$Time, include.lowest=TRUE, 
                            right=FALSE, breaks=seq(range(data$Time)[1], 
                                                  range(data$Time)[2]+1, 
                                                  by=2))) ,
                      sum)

  Group.1 ColA ColB ColC
1   [0,2)    4   17   20
2   [2,4)    3   12   14
3   [4,6)    4    5    6
4   [6,8]   10   23    4

答案 2 :(得分:0)

对于子孙后代来说,这是解决OP问题的'plyr'方法。使用'plyr'函数而不是'data.table'函数的唯一真正优势是可以使用非data.table对象。

设置:首先,以下是要使用的数据:

data <- read.table(text="
    Time ColA ColB ColC
    0    1    10   5
    1    3    7    15
    2    0    8    9
    3    3    4    5
    4    4    5    6
    7    10   23   4
    ", header=TRUE)

Ply-it :这里输入一个数据帧(d)并输出一个数据帧(d),所以我们将使用'ddply'函数。

ddply(
    data[, -1], 
    .(Time=floor(data$Time/2)), 
    colSums)

  #   Time ColA ColB ColC
  # 1    0    4   17   20
  # 2    1    3   12   14
  # 3    2    4    5    6
  # 4    3   10   23    4

我们告诉'ddply'使用变量'data'作为数据(减去包含时间的第一列),按floor(data$Time/2)索引,并使用其余部分的总和创建列通过在每组行上运行'colSums'函数来实现列。