2011-01-29 7 views
6

Supponiamo di voler ottenere alcune statistiche di riepilogo sul set di dati mtcars (parte della versione R base 2.12.1). Di seguito, raggruppo le auto in base al numero di cilindri del motore che hanno e prendono i mezzi per gruppo delle variabili rimanenti in mtcars.Come posso generare statistiche di riepilogo per gruppo se la mia variabile di raggruppamento è un fattore?

> str(mtcars) 
'data.frame': 32 obs. of 11 variables: 
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ... 
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ... 
$ disp: num 160 160 108 258 360 ... 
$ hp : num 110 110 93 110 175 105 245 62 95 123 ... 
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ... 
$ wt : num 2.62 2.88 2.32 3.21 3.44 ... 
$ qsec: num 16.5 17 18.6 19.4 17 ... 
$ vs : num 0 0 1 1 0 1 0 1 1 1 ... 
$ am : num 1 1 1 0 0 0 0 0 0 0 ... 
$ gear: num 4 4 4 3 3 3 3 4 4 4 ... 
$ carb: num 4 4 1 1 2 1 4 2 2 4 ... 
> ddply(mtcars, .(cyl), mean) 
     mpg cyl  disp  hp  drat  wt  qsec  vs  am  gear 
1 26.66364 4 105.1364 82.63636 4.070909 2.285727 19.13727 0.9090909 0.7272727 4.090909 
2 19.74286 6 183.3143 122.28571 3.585714 3.117143 17.97714 0.5714286 0.4285714 3.857143 
3 15.10000 8 353.1000 209.21429 3.229286 3.999214 16.77214 0.0000000 0.1428571 3.285714 
     carb 
1 1.545455 
2 3.428571 
3 3.500000 

Tuttavia, se la variabile di raggruppamento è un fattore, le cose diventano più complicate. ddply() genera un avviso per ogni livello del fattore, poiché non è possibile utilizzare lo mean() di un fattore.

> mtcars$cyl <- as.factor(mtcars$cyl) 
> str(mtcars) 
'data.frame': 32 obs. of 11 variables: 
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ... 
$ cyl : Factor w/ 3 levels "4","6","8": 2 2 1 2 3 2 3 1 1 2 ... 
$ disp: num 160 160 108 258 360 ... 
$ hp : num 110 110 93 110 175 105 245 62 95 123 ... 
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ... 
$ wt : num 2.62 2.88 2.32 3.21 3.44 ... 
$ qsec: num 16.5 17 18.6 19.4 17 ... 
$ vs : num 0 0 1 1 0 1 0 1 1 1 ... 
$ am : num 1 1 1 0 0 0 0 0 0 0 ... 
$ gear: num 4 4 4 3 3 3 3 4 4 4 ... 
$ carb: num 4 4 1 1 2 1 4 2 2 4 ... 
> ddply(mtcars, .(cyl), mean) 
     mpg cyl  disp  hp  drat  wt  qsec  vs  am  gear 
1 26.66364 NA 105.1364 82.63636 4.070909 2.285727 19.13727 0.9090909 0.7272727 4.090909 
2 19.74286 NA 183.3143 122.28571 3.585714 3.117143 17.97714 0.5714286 0.4285714 3.857143 
3 15.10000 NA 353.1000 209.21429 3.229286 3.999214 16.77214 0.0000000 0.1428571 3.285714 
     carb 
1 1.545455 
2 3.428571 
3 3.500000 
Warning messages: 
1: In mean.default(X[[2L]], ...) : 
    argument is not numeric or logical: returning NA 
2: In mean.default(X[[2L]], ...) : 
    argument is not numeric or logical: returning NA 
3: In mean.default(X[[2L]], ...) : 
    argument is not numeric or logical: returning NA 
> 

Quindi, mi chiedo se sto solo andando sulla generazione di statistiche di riepilogo nel modo sbagliato.

Come si generano di solito strutture dati di statistiche di riepilogo per fattore o per gruppo (come mezzi, deviazioni standard, ecc.)? Dovrei usare qualcosa di diverso da ddply()? Se posso usare ddply(), cosa posso fare per evitare gli errori che si verificano quando si tenta di prendere la media del mio fattore di raggruppamento?

risposta

8

Utilizzare numcolwise(mean): la funzione numcolwise converte il suo argomento (una funzione) in una funzione che opera solo su colonne numeriche (e ignora le colonne categoriale/fattore).

> ddply(mtcars, .(cyl), numcolwise(mean)) 

     cyl  mpg  disp  hp  drat  wt  qsec  vs 
    1 4 26.66364 105.1364 82.63636 4.070909 2.285727 19.13727 0.9090909 
    2 6 19.74286 183.3143 122.28571 3.585714 3.117143 17.97714 0.5714286 
    3 8 15.10000 353.1000 209.21429 3.229286 3.999214 16.77214 0.0000000 
      am  gear  carb 
    1 0.7272727 4.090909 1.545455 
    2 0.4285714 3.857143 3.428571 
    3 0.1428571 3.285714 3.500000 
+1

Grazie Prasad! All'epoca non mi ero neanche reso conto che avrei potuto usare una chiamata 'aggregate()' invece di una chiamata 'ddply()'. Ad esempio: 'aggregate (cbind (hp, mpg) ~ cyl, data = mtcars, mean)'. – briandk

+0

È anche un bel modo di farlo! –

+0

Prasad, questo è un trucco pratico. –

2

Non una risposta qui, ma un'osservazione. Questo non è un problema di ddply() di per sé. Guarda questo. Il seguente entrambi bene il lavoro per produrre una tabella di mezzi:

aggregate(mtcars, by=list(mtcars$cyl), mean) 
apply(mtcars, 2, function(col) tapply(col, INDEX=mtcars$cyl, FUN=mean)) 

Ma dopo mtcars$cyl <- as.factor(mtcars$cyl) né del lavoro di cui sopra, perché R non sa come prendere la media di una colonna di fattori. Siamo in grado di evitarlo, eliminando quella colonna ("cil" è la colonna 2) dalle cose passate per mean():

aggregate(mtcars[ , -2], by=list(mtcars$cyl), mean) 
apply(mtcars[ , -2], 2, function(col) tapply(col, INDEX=mtcars$cyl, FUN=mean)) 

Ma che è piuttosto goffo.

+0

grazie! L'ho provato io stesso, e hai perfettamente ragione: il problema è che R non sa come prendere la media di un fattore, e io stavo lottando con i modi per aggirare il problema. La tua strada funziona sicuramente, sebbene 'aggregate()' ti permetta di specificare quali colonne includere: 'aggregate (cbind (hp, mpg) ~ cyl, data = mtcars, mean)' – briandk

Problemi correlati