我正在尝试使用R的by
命令来获取数据帧子集的列方式。例如,请考虑以下数据框:
> z = data.frame(labels=c("a","a","b","c","c"),data=matrix(1:20,nrow=5))
> z
labels data.1 data.2 data.3 data.4
1 a 1 6 11 16
2 a 2 7 12 17
3 b 3 8 13 18
4 c 4 9 14 19
5 c 5 10 15 20
我可以使用R的by
命令根据标签列获取列的含义:
> by(z[,2:5],z$labels,colMeans)
z[, 1]: a
data.1 data.2 data.3 data.4
1.5 6.5 11.5 16.5
------------------------------------------------------------
z[, 1]: b
data.1 data.2 data.3 data.4
3 8 13 18
------------------------------------------------------------
z[, 1]: c
data.1 data.2 data.3 data.4
4.5 9.5 14.5 19.5
但是如何将输出强制回数据框? as.data.frame
不起作用......
> as.data.frame(by(z[,2:5],z$labels,colMeans))
Error in as.data.frame.default(by(z[, 2:5], z$labels, colMeans)) :
cannot coerce class '"by"' into a data.frame
答案 0 :(得分:11)
您可以使用ddply
包
plyr
library(plyr)
ddply(z, .(labels), numcolwise(mean))
labels data.1 data.2 data.3 data.4
1 a 1.5 6.5 11.5 16.5
2 b 3.0 8.0 13.0 18.0
3 c 4.5 9.5 14.5 19.5
aggregate
来自stats
aggregate(z[,-1], by=list(z$labels), mean)
Group.1 data.1 data.2 data.3 data.4
1 a 1.5 6.5 11.5 16.5
2 b 3.0 8.0 13.0 18.0
3 c 4.5 9.5 14.5 19.5
或来自dcast
包
reshape2
library(reshape2)
dcast( melt(z), labels ~ variable, mean)
使用sapply
:
t(sapply(split(z[,-1], z$labels), colMeans))
data.1 data.2 data.3 data.4
a 1.5 6.5 11.5 16.5
b 3.0 8.0 13.0 18.0
c 4.5 9.5 14.5 19.5
答案 1 :(得分:9)
by
的输出为list
,因此您可以do.call
使用rbind
,然后将其转换为:
as.data.frame(do.call("rbind",by(z[,2:5],z$labels,colMeans)))
data.1 data.2 data.3 data.4
a 1.5 6.5 11.5 16.5
b 3.0 8.0 13.0 18.0
c 4.5 9.5 14.5 19.5
答案 2 :(得分:0)
处理 by 输出可能非常烦人。我刚刚找到了一种以数据框格式提取所需内容的方法,但您不需要额外的包。
所以,如果你这样做:
aux <- by(z[,2:5],z$labels,colMeans)
然后,您可以通过执行以下操作在数据框中对其进行转换:
aux_df <- as.data.frame(t(aux[seq(nrow(aux)),seq(ncol(aux))]))
我只是从aux获取所有行和列,转置它并使用as.data.frame。
我希望有所帮助。