2012-09-12 19 views
7

Sto tentando di utilizzare il comando R by per ottenere i mezzi di colonna per i sottoinsiemi di un frame di dati. Ad esempio, si consideri questo frame di dati:conversione dell'output del comando "by" di R nel frame dati

> 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 

posso usare comando di R by vedere la colonna mezzi secondo la colonna etichette:

> 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 

Ma come faccio costringere l'uscita torna a un data telaio? as.data.frame non funziona ...

> 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 

risposta

11

È possibile utilizzare ddply da plyr pacchetto

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 

O aggregate da 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 

O dcast da reshape2 pacchetto

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

Utilizzando 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

Ottimo! Tutti fanno ciò che stavo cercando, anche se "aggregare" sembra il più semplice (e il più semplice per me di capire di nuovo in futuro). Grazie! – Andrew

8

L'uscita del by è un list in modo da poter usare do.call-rbind loro e poi convertire questo:

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

Trattare con la da uscita può essere davvero fastidioso Ho appena trovato un modo per ritirare ciò che vuoi in un formato di un frame di dati e non avrai bisogno di pacchetti aggiuntivi.

Quindi, se si esegue questa operazione:

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

È quindi possibile trasformarlo in un frame di dati in questo modo:

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

Sto ricevendo tutte le righe e le colonne da aux , trasponendolo e usando as.data.frame.

Spero che questo aiuti.

Problemi correlati