2013-01-05 12 views
6

Czy ktoś może mi pomóc uzyskać różnicę między kruszywa i ddply z poniższym przykładzie:różnica między ddply i kruszywo

Ramka danych:

mydat <- data.frame(first = rpois(10,10), second = rpois(10,10), 
        third = rpois(10,10), group = c(rep("a",5),rep("b",5))) 

Zastosowanie kruszywa zastosować funkcję do części ramka danych podzielone przez współczynnik:

aggregate(mydat[,1:3], by=list(mydat$group), mean) 
    Group.1 first second third 
1  a 8.8 8.8 10.2 
2  b 6.8 9.4 13.4 

spróbuje użyć kruszywo do innej funkcji (zwraca komunikat o błędzie):

aggregate(mydat[,1:3], by=list(mydat$group), function(u) cor(u$first,u$second)) 
Error in u$second : $ operator is invalid for atomic vectors 

Teraz, spróbuj to samo z ddply (pakiet plyr):

ddply(mydat, .(group), function(u) cor(u$first,u$second)) 
    group   V1 
1  a -0.5083042 
2  b -0.6329968 

Wszystkie porady, linki, krytyka są wysoko cenione.

+0

myślę, że wykazał różnicę. Czy jest tu pytanie? –

+3

Cóż, chociaż widzę, że jest różnica, nie rozumiem, dlaczego tak jest. Co w tych funkcjach powoduje różnicę, którą pokazuję? – skip

+2

Część 5 http://programming-r-pro-bro.blogspot.com/2012/12/r-faqs-for-fresh-starters.html zawiera niesamowite wyjaśnienie z przykładowym kodem. Zasadniczo, ddply pozwala na użycie RÓŻNYCH funkcji dla każdej zmiennej, podczas gdy agregacja zmusza do użycia tej samej funkcji dla wszystkich kolumn, które przechodzą. –

Odpowiedz

12

aggregate dzwoń ZABAWY na każdej kolumnie niezależnie, dzięki czemu uzyskasz niezależne środki. ddply przejdzie wszystkie kolumny do funkcji. Szybkie demonstracja tego, co jest przekazywane w aggregate może być w porządku:

Niektóre przykładowe dane dotyczące demonstracji:

d <- data.frame(a=1:4, b=5:8, c=c(1,1,2,2)) 

> d 
    a b c 
1 1 5 1 
2 2 6 1 
3 3 7 2 
4 4 8 2 

Stosując funkcję print i ignorując wynik poleceń aggregate lub ddply możemy zobacz, co zostanie przekazane do funkcji w każdej iteracji.

aggregate:

tmp <- aggregate(d[1:2], by=list(d$c), print) 
[1] 1 2 
[1] 3 4 
[1] 5 6 
[1] 7 8 

Należy pamiętać, że poszczególne kolumny są wysyłane do wydrukowania.

ddply:

tmp <- ddply(d, .(c), print) 
    a b c 
1 1 5 1 
2 2 6 1 
    a b c 
3 3 7 2 
4 4 8 2 

Należy pamiętać, że ramki danych są wysyłane do wydrukowania.

+0

Fajnie, dziękuję: pierwsze dwa zdania zawierają dokładnie to, czego szukałem. – skip

+0

@Arun To, co wkleiłem, jest wynikiem działania 'print' w' aggregate'. Pominąłem wynik z 'agregatu', który nie jest ważny dla tego przykładu. Będę edytować odpowiedź, aby lepiej to zaznaczyć. –

6

Odpowiedź @MatthewLundberg, jest bardzo dobra, moja nie jest odpowiedzią, ale jest to tylko ogólna wskazówka, której używam, gdy chcę zobaczyć, co dzieje się za wywołaniem niektórych funkcji R. Używam polecenia debugowania browser.

aggregate(mydat[,1:3], by=list(mydat$group), 
+   function(x){ 
+    browser() 
+    mean(x) 
+   }) 
Called from: FUN(X[[1L]], ...) 
Browse[1]> x 
[1] 16 10 16 13 25 

następnie do ddply

ddply(mydat, .(group), function(u) { 
+ browser() 
+ cor(u$first,u$second) 
+ }) 
Called from: .fun(piece, ...) 
Browse[1]> u 
    first second third group 
1 16  8  9  a 
2 10  6  6  a 
3 16  6 10  a 
4 13  8 10  a 
5 25  10  4  a 

Edit debugowania błędu przez siebie

Tutaj używam techniki zrozumieć, dlaczego masz błąd

aggregate(mydat[,1:3], by=list(mydat$group), function(u) { 
+ browser() 
+ cor(u$first,u$second) 
+ }) 
Called from: FUN(X[[1L]], ...) 
Browse[1]> u 
[1] 16 10 16 13 25  

jak ty patrz tutaj u jest wektorem atomowym (bez nazw kolumn) Więc jeśli spróbujesz

Browse[1]> u$first 

Otrzymasz błąd:

Error in u$first : $ operator is invalid for atomic vectors 
7

Już powiedziano dlaczego aggregate był zły baza {} function użyć dla funkcji, która wymaga dwóch wektorów jako argumenty , ale jeszcze nie powiedziano ci, które podejście nie przyniosłoby oczekiwanego rezultatu.

by(... grp, FUN) metoda:

> cbind (by(mydat, mydat["group"], function(d) cor(d$first, d$second))) 
     [,1] 
a 0.6529822 
b -0.1964186 

sapply(split(..., grp), fn) metoda

> sapply( split(mydat, mydat["group"]), function(d) cor(d$first, d$second)) 
     a   b 
0.6529822 -0.1964186 
+1

Zawsze czuję się winna, gdy odwołuję się do 'plyr/ddply', ponieważ mam na myśli to, że zawiodłem lub byłem zbyt niecierpliwy, rozumiejąc agregację, działanie lub tapply. Zauważ jednak, że 'ddply' jest tak ogólne, że może być wolne dla dużych problemów. Szybka wersja ddply rośnie tutaj: https://github.com/hadley/dplyr. –