R:汇总数据框的列

7

I have a data.frame that looks like this

> head(df)
            Memory    Memory    Memory    Memory    Memory     Naive     Naive
10472501  6.075714  5.898929  6.644946  6.023901  6.332126  8.087944  7.520194
10509163  6.168941  6.495393  5.951124  6.052527  6.404401  7.152890  8.335509
10496091 10.125575  9.966211 10.075613 10.310952 10.090649 11.803949 11.274480
10427035  6.644921  6.658567  6.569745  6.499243  6.990852  8.010784  7.798154
10503695  8.379494  8.153917  8.246484  8.390747  8.346748  9.540236  9.091740
10451763 10.986717 11.233819 10.643245 10.230697 10.541396 12.248487 11.823138  

我希望找到Memory列和Naive列的平均值。 aggregate函数用于聚合行。这个data.frame可能有大量的行,因此转置然后按原始data.framecolnames应用aggregate似乎不太好,而且通常很烦人:

> head(t(aggregate(t(df),list(colnames(df)), mean)))
         [,1]       [,2]      
Group.1  "Memory"   "Naive"   
10472501 "6.195123" "8.125439"
10509163 "6.214477" "7.733625"
10496091 "10.11380" "11.55348"
10427035 "6.672665" "8.266854"
10503695 "8.303478" "9.340436"

我错过了什么非常明显的事情吗?

1
敏锐的读者会注意到8.12不是8.08和7.52的平均值:实际上还有一些列。但并不多! - Mike Dewar
5个回答

8
我是一个大力倡导将数据重新格式化为“长”格式的人。当处理像这样的问题时,“长”格式的效用尤其明显。幸运的是,使用"reshape"包可以轻松地将数据重塑成几乎任何格式。
如果我正确理解了您的问题,您想要每行的“Memory”和“Naive”的平均值。出于某种原因,我们需要使reshape::melt()中的列名唯一。
colnames(df) <- paste(colnames(df), 1:ncol(df), sep = "_")

然后,您需要创建一个ID列。您可以选择执行以下操作:
df$ID <- 1:nrow(df)

或者,如果这些行名称有意义。
df$ID <- rownames(df)

现在,使用reshape包。
library(reshape)
df.m <- melt(df, id = "ID")
df.m <- cbind(df.m, colsplit(df.m$variable, split = "_", names = c("Measure", "N")))
df.agg <- cast(df.m, ID ~ Measure, fun = mean)

df.agg现在应该类似于你所期望的输出片段。

或者,如果你只想要所有行的总体平均值,Zack的建议也可以。类似于:

m <- colMeans(df)
tapply(m, colnames(df), mean)

您可以获得相同的结果,但格式化为数据框:
cast(df.m, .~variable, fun = mean)

因为这似乎是正确的做法,所以感谢Jo!但是正如John所说,我错过的显而易见的事情就是rowMeans函数,这是我不会再忘记的东西! - Mike Dewar
嗯,快问一下。你有没有想法为什么 s <- cast(df.m, ID ~ variable, fun = var) 返回了一堆零,而 fun = mean 似乎正常工作,'fun=sum` 也可以?这些列的方差肯定不是零。 - Mike Dewar
好的发现!我不知道问题出在哪里,但由于列名不唯一,它们没有正确地融合。我已经编辑了我的答案,现在应该可以工作了! - JoFrhwld
我已将此问题扩展为更一般的问题:http://stackoverflow.com/questions/3356923/r-reshape-variance-of-columns-of-a-data-frame 你能详细阐述一下吗? - Mike Dewar

4

你觉得这样怎么样?

l <-lapply(unique(colnames(df)), function(x) rowMeans(df[,colnames(df) == x]))



df <- do.call(cbind.data.frame, l)

谢谢Jonathan!这正是我大脑中某个部分告诉我存在的,我只是想不起来。 - Mike Dewar

3
为了澄清Jonathan Chang的回答...你忽略的显而易见的事情是,您可以选择列并发出rowMeans命令。 这将为每行提供均值向量。 他的命令获取唯一列名称组的行平均值,正是我要写的。 使用您的示例数据,他的命令的结果是两个列表。
rowMeans也非常快。
要分解它,请只获取所有内存列的平均值
rowMeans(df[,colnames(df) == 'Memory']) #or from you example, rowMeans(df[,1:5])

这是最简单且完整正确的答案,如果你喜欢,请给他点赞并将其标记为正确答案。

(顺便说一句,我也喜欢Jo的建议,将通常的事情保存为长数据。)


0
m = matrix(1:12,3)
colnames(m) = c(1,1,2,2)

m

     1 1 2  2
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12

mt = t(m)
sapply(by(mt,rownames(mt),colMeans),identity)

     1    2
V1 2.5  8.5
V2 3.5  9.5
V3 4.5 10.5

你能提供一个解释吗? - Anubian Noob

0

我认为你已经加载了没有 header=TRUE 的数据,所以你拥有的是一个因子矩阵,因此你通常的好想法失败了。


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