2010-07-27 93 views
6

的聚合列我有一個data.frame看起來像這樣R:一個data.frame

> 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的意思是:有一些更多的列事實上。雖然沒有更多! – 2010-07-27 22:44:17

回答

8

我什麼格式化數據的一大主張,這樣很「長」格式。當涉及到這樣的問題時,長格式的效用尤其明顯。幸運的是,使用reshape軟件包將這種數據重塑爲幾乎任何格式都很容易。

如果我理解你的問題的權利,你需要每行的MemoryNaive的意思。無論出於何種原因,我們需要爲reshape::melt()設定唯一的列名稱。

colnames(df) <- paste(colnames(df), 1:ncol(df), sep = "_") 

然後,您將不得不創建一個ID列。你既可以做

df$ID <- 1:nrow(df) 

或者,如果這些rownames是有意義現在

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現在應該看起來像你期望的輸出SNIPPIT。或者,如果您只想整個行的整體含義,那麼Zack的建議就可以發揮作用。像

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

東西,你可以得到相同的結果,但格式化爲數據幀與

cast(df.m, .~variable, fun = mean) 
+0

給喬打勾,因爲這似乎是正確的做事方式,非常感謝!但是,是的,正如約翰所說,我錯過的顯而易見的事情就是rowMeans函數,這是我不會再忘記的! – 2010-07-28 19:08:57

+0

呃 - 快速的問題。任何知道爲什麼'< - cast(df.m,ID〜variable,fun = var)'給我一大堆零,當'fun = mean'似乎工作正常並且'fun = sum'也可以工作?這些列的方差不是零。 – 2010-07-28 19:41:13

+0

好抓!我不知道這筆交易是什麼,但由於列名並非唯一,所以它們沒有正確融化。我編輯了我的答案,以便它現在能夠工作! – JoFrhwld 2010-07-28 20:03:11

0

我想你已經加載了你的數據而沒有header=TRUE,你有什麼是一個因子矩陣,所以你的一般好主意失敗。

3

關於類似

lapply(unique(colnames(df)), function(x) rowMeans(df[,colnames(df) == x])) 
+0

謝謝喬納森!這就是我的大腦的某些部分告訴我存在,我只是不記得它。 – 2010-07-28 19:09:43

3

澄清喬納森暢的答案...你缺少一味明顯的事情是,你可以選擇列併發出rowMeans命令。這將爲每一行提供方法的向量。他的命令爲每組獨特的列名獲取行手段,這正是我要寫的內容。使用您的示例數據,他的命令的結果是兩個列表。

rowMeans也非常快。

要打破它,讓所有的內存列的唯一手段就是

rowMeans(df[,colnames(df) == 'Memory']) #or from you example, rowMeans(df[,1:5]) 

這是最簡單的完全正確的答案,投票他,並標出了他正確的,如果你喜歡它。

(順便說一句,我也很喜歡喬的建議,以保持通常的事情,只要數據。)

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 
+0

你能提供一個解釋嗎? – 2014-06-16 03:46:44