2013-07-19 23 views
6

Mam zestaw danych zawierający dane testowe prototypu produktu. Nie wszystkie testy zostały przeprowadzone na wszystkich partiach i nie wszystkie testy zostały wykonane z tymi samymi próbkami. Aby zilustrować, należy rozważyć tę sprawę:Mieszanka na.omit i na.pass przy użyciu agregatu?

> 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 

W przeszłości miałem tylko do czynienia z przypadkami sparowane powtórzeń, co nie było łatwe z aggregate(cbind(var1, var2) ~ name, test, FUN = mean, na.action = na.omit) (lub ustawienie domyślne). Otrzymam średnie dla każdej partii na trzy wartości dla var1 i ponad cztery wartości dla var2.

Niestety, będzie to zostawić mnie z zestawu danych całkowicie brakującej partii A w tym przypadku:

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 

Jeśli używam na.pass jednak, ja też nie rozumiem, czego chcę:

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 

Teraz tracę dobre dane, które miałem w var1, ponieważ zawierały instancje NA.

Co chciałbym to:

  • NA jako wyjście mean() jeżeli wszystkich unikalnych kombinacji varN ~ nameNA s
  • Wyjście mean() jeśli istnieje jeden lub więcej wartości rzeczywiste dla varN ~ name

Zgaduję, że to jest pre tty proste, ale po prostu nie wiem jak. Czy muszę użyć ddply czegoś takiego? Jeśli tak ... powodem staram się go unikać, że skończę pisać bardzo długie odpowiedniki aggregate() tak:

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

... Tak więc wynikiem, że najwyraźniej robi to, co chcę. I tak pozostawiam pytanie na wypadek, gdyby był 1) sposób na zrobienie tego przy pomocy aggregate() lub 2) krótszej składni dla ddply.

+0

Ponownie potknął się o jedną odpowiedź ponownie. 'ddply' [TUTAJ] (http://stackoverflow.com/questions/10787640/r-ddply-summarize-with- large-lumber-of-columns). Zasadniczo, rozpakuj ramkę danych, zastosuj "mean()" w oparciu o kombinacje zmiennej i pierwszej nazwy kolumny, a następnie odrzuć ją do pierwotnego kształtu. Ktoś jeszcze? – Hendy

Odpowiedz

16

Przepuścić zarównona.action=na.pass i na.rm=TRUE do aggregate. Pierwsza z nich mówi, aby nie usuwać wierszy, w których istnieją NA; a ten drugi mówi, że aby je zignorować, musi być mean.

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

Awesome, i nie miałem pojęcia, że ​​to było możliwe. – Hendy

+0

@HongOoi To działało świetnie. Po prostu o czymś wartym uwagi, to zastąpi NA wartościami zerowymi w zależności od wybranej funkcji. Najprawdopodobniej nie jest to końcowy wynik, który chcesz, więc pamiętaj o kontynuowaniu czegoś takiego jak 'df [df == 0] <- NA'. Jeśli masz rzeczywiste zera w swoim df, którego nie chcesz usunąć, to połącz powyższy kod z 'is.na (df)' –

+0

główkami w górę zwraca 'NaN', zamiast' NA' dla nazwy 'A', 'var3' – colin