2013-07-19 3 views
6

Ich habe einen Datensatz mit Produktprototypen Testdaten. Nicht alle Tests wurden auf allen Losen durchgeführt, und nicht alle Tests wurden mit den gleichen Stichprobengrößen ausgeführt. Zur Veranschaulichung betrachte diesen Fall:Mischung von na.omit und na.pass mit Aggregat?

> 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 der Vergangenheit habe ich nur mit Fällen von nicht abgestimmten Wiederholungen zu behandeln, die mit aggregate(cbind(var1, var2) ~ name, test, FUN = mean, na.action = na.omit) leicht gewesen sind (oder die Standardeinstellung). Ich werde Durchschnittswerte für jedes Los über drei Werte für var1 und über vier Werte für var2 erhalten.

Leider wird diese mich verlassen mit einem Datensatz vollständig fehlt viel A in diesem Fall:

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 

Wenn ich na.pass verwenden, aber ich auch nicht bekommen, was ich will:

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 

Jetzt verliere ich die guten Daten, die ich in var1 hatte, da es Instanzen von NA enthielt.

Was würde Ich mag ist:

  • NA als die Ausgabe von mean() wenn alle einzigartigen Kombinationen von varN ~ name sind NA s
  • Ausgabe von mean() wenn es einer oder mehr Istwerten für varN ~ name

Ich schätze, das ist vor tty einfach, aber ich weiß einfach nicht wie. Muss ich ddply für so etwas verwenden? Wenn ja ... der Grund, neige ich dazu, es zu vermeiden, ist, dass ich mit dem Schreiben am Ende wirklich lange Äquivalente aggregate() wie so:

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

Ja ... so das Ergebnis, dass offenbar das tut, was ich will. Ich werde die Frage trotzdem lassen, falls es 1) einen Weg gibt, dies mit aggregate() oder 2) kürzere Syntax für ddply zu tun.

+0

Re-stumbled auf eine Antwort re. 'ddply' [HIER] (http://stackoverflow.com/questions/10787640/r-ddply-summarize-with-large-number-of-columns). Im Grunde schmelzen Sie den Datenrahmen, wenden Sie 'mean()' an, basierend auf Kombinationen der interessierenden Variable und des früheren Spaltennamens, und werfen Sie ihn dann zurück auf die ursprüngliche Form. Irgendwelche anderen? – Hendy

Antwort

16

Pass beidena.action=na.pass und na.rm=TRUE zu aggregate. Ersteres sagt aggregate, Zeilen nicht zu löschen, in denen NAs existieren; und letzteres sagt mean, sie zu ignorieren.

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

Super, und ich hatte keine Ahnung, dass das möglich war. – Hendy

+0

@HongOoi Das hat super funktioniert. Nur etwas zu beachten, dies wird die NAs durch Nullen ersetzen, abhängig davon, welche Funktion Sie wählen. Dies ist höchstwahrscheinlich nicht das Endergebnis, das Sie wollen, seien Sie also sicher, dass Sie etwas wie "df [df == 0] <- NA" verfolgen. Wenn du echte Nullen in deinem df hast, die du nicht entfernen willst, kombiniere den obigen Code mit 'is.na (df)' –

+0

heads up, das gibt 'NaN' zurück, anstatt' NA' für den Namen 'A', 'var3' – colin