如何使用R在多列数据帧上运行tapply()?

时间:2011-08-11 16:49:28

标签: r data-manipulation

我有一个如下数据框:

a   b1  b2  b3  b4  b5  b6  b7  b8  b9
D   4   6   9   5   3   9   7   9   8
F   7   3   8   1   3   1   4   4   3
R   2   5   5   1   4   2   3   1   6
D   9   2   1   4   3   3   8   2   5
D   5   4   3   1   6   4   1   8   3
R   3   7   9   1   8   5   3   4   2
D   4   1   8   2   6   3   2   7   5
F   7   1   7   2   7   1   6   2   4
D   6   3   9   3   9   9   7   1   2

函数tapply(df[,2], INDEX = df$a, sum)可以正常生成一个表,该表以df [a]对df [,2]中的所有内容求和,但当我尝试tapply(df[,2:10], INDEX = df$a, sum)得到一个类似的表时,除了一个总和每列(2,3,4,...,10),我收到一条错误信息:

  

tapply错误(df [,2:10],INDEX = df $ a,sum):参数必须具有相同的长度

此外,我希望表的行名是df[,2:10]的列名,这样第1行是b1,第2行是b2,第9行是b9。

3 个答案:

答案 0 :(得分:18)

那是因为tapply适用于矢量,并将df [,2:10]转换为矢量。接下来,sum将给出总和,而不是每列的总和。使用aggregate(),例如:

aggregate(df[,2:10],by=list(df$a), sum)

如果要返回列表,可以使用by()。确保指定colSums而不是sum,因为它适用于拆分的数据框:

by(df[,2:10],df$a,FUN=colSums)

答案 1 :(得分:7)

另一种可能性是合并applytapply

apply(df[,-1], 2, function(x) tapply(x, df$a, sum))

将产生输出(这是一个矩阵)

    b1  ...   b9
D   sD1 ...  sD9
F   sF1 ...  sF9
R   sR1 ...  sR9

然后,您可以使用as.data.frame()将数据框作为输出。

答案 2 :(得分:6)

以下是一种将data.table应用于此问题的方法。

library(data.table)
DT <- data.table(df)
DT[, lapply(.SD, sum), by=a]

这是dplyr方法

library(dplyr)
df %>% group_by(a) %>% summarise_all(funs(sum))