2014-07-16 49 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