2013-07-19 20 views
6

Ho un set di dati contenente dati di test del prototipo del prodotto. Non tutti i test sono stati eseguiti su tutti i lotti e non tutti i test sono stati eseguiti con le stesse dimensioni del campione. Per illustrare, consideriamo questo caso:Miscela di na.omit e na.pass utilizzando l'aggregato?

> test <- data.frame(name = rep(c("A", "B", "C"), each = 4), 
    var1 = rep(c(1:3, NA), 3), 
    var2 = 1:12, 
    var3 = c(rep(NA, 4), 1:8)) 

> test 
    name var1 var2 var3 
1  A 1 1 NA 
2  A 2 2 NA 
3  A 3 3 NA 
4  A NA 4 NA 
5  B 1 5 1 
6  B 2 6 2 
7  B 3 7 3 
8  B NA 8 4 
9  C 1 9 5 
10 C 2 10 6 
11 C 3 11 7 
12 C NA 12 8 

In passato, ho avuto solo a che fare con casi di male assortita ripetizioni, che è stato facile con aggregate(cbind(var1, var2) ~ name, test, FUN = mean, na.action = na.omit) (o l'impostazione di default). Otterrò una media per ogni lotto su tre valori per var1 e su quattro valori per var2.

Purtroppo, questo mi lascerà con un set di dati del tutto mancante molto A in questo caso:

aggregate(cbind(var1, var2, var3) ~ name, test, FUN = mean, na.action = na.omit) 
    name var1 var2 var3 
1 B 2 6 2 
2 C 2 10 6 

Se uso na.pass, però, anche io non ottengo quello che voglio:

aggregate(cbind(var1, var2, var3) ~ name, test, FUN = mean, na.action = na.pass) 
    name var1 var2 var3 
1 A NA 2.5 NA 
2 B NA 6.5 2.5 
3 C NA 10.5 6.5 

Ora ho perso i buoni dati che avevo in var1 poiché conteneva istanze di NA.

Quello che mi piace è:

  • NA come l'uscita di mean() se tutti combinazioni uniche di varN ~ name sono NA s
  • uscita di mean() se ci sono uno o più valori effettivi per varN ~ name

Sto supponendo che questo è pre tty semplice, ma non so come. Devo usare ddply per qualcosa di simile? Se è così ... il motivo tendo a evitarlo è che io alla fine a scrivere davvero lunghe equivalenti a aggregate() in questo modo:

ddply(test, .(name), summarise, 
    var1 = mean(var1, na.rm = T), 
    var2 = mean(var2, na.rm = T), 
    var3 = mean(var3, na.rm = T)) 

Già ... in modo che il risultato di che fa a quanto pare quello che voglio. Lascerò comunque la domanda nel caso in cui ci sia 1) un modo per farlo con aggregate() o 2) sintassi più breve per ddply.

+0

Ripetuto in una risposta ri. 'ddply' [QUI] (http://stackoverflow.com/questions/10787640/r-ddply-summarize-with-large-number-of-columns). Fondamentalmente, fondere il frame dei dati, applicare 'mean()' in base alle combinazioni della variabile di interesse e al nome della colonna precedente, quindi riportarlo alla forma originale. Chiunque altro? – Hendy

risposta

16

Passo siana.action=na.pass e na.rm=TRUE-aggregate. Il primo dice a aggregate di non cancellare le righe in cui esistono NA; e quest'ultimo dice a mean di ignorarli.

aggregate(cbind(var1, var2, var3) ~ name, test, mean, 
      na.action=na.pass, na.rm=TRUE) 
+0

Fantastico, e non avevo idea che fosse possibile. – Hendy

+0

@HongOoi Questo ha funzionato alla grande. Solo qualcosa da notare, questo sostituirà gli AN con zeri a seconda della funzione scelta. Molto probabilmente questo non è il risultato finale che vuoi, quindi assicurati di seguire qualcosa come 'df [df == 0] <- NA'. Se nel tuo df hai zeri reali che non vuoi rimuovere, allora combina il codice sopra con 'is.na (df)' –

+0

controlla questo 'NaN' restituito, piuttosto che' NA' per il nome 'A', 'var3' – colin