2014-07-16 51 views
4

我有這樣一個大的數據幀:我怎樣才能在每一列獲得手段?

ID c_Al c_D c_Hy  occ 
A  0  0  0  2306 
B  0  0  0  3031 
C  0  0  1  2581 
D  0  0  1  1917 
E  0  0  1  2708 
F  0  1  0  2751 
G  0  1  0  1522 
H  0  1  0  657 
I  0  1  1  469 
J  0  1  1  2629 
L  1  0  0  793 
L  1  0  0  793 
M  1  0  0  564 
N  1  0  1  2617 
O  1  0  1  1167 
P  1  0  1  389 
Q  1  0  1  294 
R  1  1  0  1686 
S  1  1  0  992 

我怎樣才能手段中的每一列?

​​

我試過aggregate(occ~c_Al, mean, data=table2),但它必須做很多次; ddply具有相同的結果,或for(i in 1:dim(table2)[1]){ aggregate(occ~[,i], mean, data=table2)},但它不能工作。

+0

也許更簡單一些,比如'colMeans'? – AndrewMacDonald

+0

您的結果僅僅是您想要的格式或您期望得到的實際結果的示例? – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto它只是一個例子 – Hannah

回答

10

我只想用meltdcast從 「reshape2」:

library(reshape2) 
dfL <- melt(table2, id.vars = c("ID", "occ")) 
dcast(dfL, variable ~ value, value.var = "occ", fun.aggregate = mean) 
# variable  0  1 
# 1  c_Al 2057.100 1032.778 
# 2  c_D 1596.667 1529.429 
# 3  c_Hy 1509.500 1641.222 

當然,基礎R可以處理這個就好了。

在這裏,我用tapplyvapply

vapply(table2[2:4], function(x) tapply(table2$occ, x, mean), numeric(2L)) 
#  c_Al  c_D  c_Hy 
# 0 2057.100 1596.667 1509.500 
# 1 1032.778 1529.429 1641.222 
t(vapply(table2[2:4], function(x) tapply(table2$occ, x, mean), numeric(2L))) 
#    0  1 
# c_Al 2057.100 1032.778 
# c_D 1596.667 1529.429 
# c_Hy 1509.500 1641.222 
+0

*愛*這種'vapply'的使用! – AndrewMacDonald

+0

@AndrewMacDonald,謝謝! 'sapply'這樣做很好,但是由於'simpl2array'通常比較慢,所以現在當我有機會的時候,我更喜歡'vapply'。 – A5C1D2H2I1M1N2O1R2T1

3

我通過dplyrtidyr嘗試這個。類似@ akrun的做法,但在一個「更廣泛」的格式保存數據(沒有特殊原因)

library(tidyr) 
library(dplyr) 

new_df <- df %>% 
    gather(category,value,c_Al:c_Hy) %>% 
    mutate(ids = 1:n()) %>% 
    #unique %>% 
    spread(value,occ,fill = NA) 

mean_na <- function(x) mean(x,na.rm = TRUE) 

new_df %>% 
    group_by(category) %>% 
    select(-ID,-ids) %>% 
    summarise_each(funs(mean_na)) 

    category  0  1 
1  c_Al 2057.100 1032.778 
2  c_D 1596.667 1529.429 
3  c_Hy 1509.500 1641.222 
+1

我不認爲這些結果是正確的。嘗試手動計算並查看。 – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto完全正確!事實證明,人們必須小心地將其定義爲「填充」值; P – AndrewMacDonald

+0

現在更好。 +1。 (但是你現在需要編輯你的第一句話)。 – A5C1D2H2I1M1N2O1R2T1

4

使用dplyr。如果dat是數據集

library(dplyr) 
library(tidyr) 

dat%>% 
gather(Var,Value, c_Al:c_Hy)%>% 
group_by(Value,Var)%>% 
summarize(occ=mean(occ))%>% 
spread(Value, occ) 
Source: local data frame [3 x 3] 

# Var  0  1 
# 1 c_Al 2057.100 1032.778 
# 2 c_D 1596.667 1529.429 
# 3 c_Hy 1509.500 1641.222 
+0

比我的更好 - 雙重組合是去這裏的方式;當然更容易閱讀。 – AndrewMacDonald

1

替代純R:

sapply(0:1, 
     function(i) sapply(colnames(df[2:4]), 
          function(column) mean(df[df[,column]==i, "occ"]))) 

編輯:或,如在將結果與colnames請求(:由矢量與命名的元素1代替0):

sapply(c("0"=0, "1"=1), 
     function(i) sapply(colnames(df[2:4]), 
          function(column) mean(df[df[,column]==i, "occ"]))) 
+0

+1。儘管在那裏添加「colnames」會很好。 – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto:感謝您的建議,並對其進行了更新。 – Martin

1

這是一個解決方案,只使用colSums和子集考慮問題的矩陣結構:

cbind(`0`=colSums((x[,2:4]-1)*x[,5]*-1)/colSums(x[,2:4]==0), 
     `1`=colSums(x[,2:4]*x[,5])/colSums(x[,2:4]==1)) 
      0  1 
c_Al 2057.100 1032.778 
c_D 1596.667 1529.429 
c_Hy 1509.500 1641.222