2012-09-12 28 views
7

Tôi đang cố sử dụng lệnh by của R để lấy cột có nghĩa là cho các tập hợp con của một khung dữ liệu. Ví dụ, hãy xem xét khung dữ liệu này:chuyển đổi đầu ra của lệnh "by" của R thành khung dữ liệu

> 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 

tôi có thể sử dụng lệnh R của by để có được những cột có nghĩa là theo các nhãn cột:

> 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 

Nhưng làm thế nào để ép buộc đầu ra trở lại một dữ liệu khung? as.data.frame không hoạt động ...

> 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 

Trả lời

11

Bạn có thể sử dụng ddply từ plyr gói

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 

Hoặc aggregate từ 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 

Hoặc dcast từ reshape2 gói

library(reshape2) 
dcast(melt(z), labels ~ variable, mean) 

Sử dụng 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 
+0

Tuyệt vời! Tất cả làm những gì tôi đang tìm kiếm, mặc dù 'aggregate' có vẻ đơn giản nhất (và đơn giản nhất cho tôi để tìm ra một lần nữa trong tương lai). Cảm ơn! – Andrew

8

Kết quả của by là một list vì vậy bạn có thể sử dụng do.call-rbind họ và sau đó chuyển đổi này:

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 
0

Đối phó với những bởi đầu ra có thể thực sự gây phiền nhiễu. Tôi chỉ tìm thấy một cách để rút những gì bạn muốn trong một định dạng của một khung dữ liệu và bạn sẽ không cần gói thêm.

Vì vậy, nếu bạn làm điều này:

aux <- by(z[,2:5],z$labels,colMeans) 

Sau đó bạn có thể chuyển đổi nó trong một khung dữ liệu bằng cách làm này:

aux_df <- as.data.frame(t(aux[seq(nrow(aux)),seq(ncol(aux))])) 

Tôi chỉ nhận được tất cả các hàng và cột từ aux , chuyển nó và sử dụng as.data.frame.

Tôi hy vọng điều đó sẽ hữu ích.

Các vấn đề liên quan