2014-05-20 14 views
7

Mam bardzo dużą ramkę danych (265,874 x 30), z trzema rozsądnymi grupami: kategorią wiekową (1-6), datami (5479) i geograficznymi miejscowość (4 łącznie). Każdy rekord składa się z wyboru każdego z nich plus 27 zmiennych liczbowych. Chcę grupować według każdej zmiennej grupującej, a następnie pobrać colSums na wynikowych 27 podgrupach podzielonych na podgrupy. Próbowałem użyć dplyr (v0.2), aby to zrobić, ponieważ robienie tego ręcznie kończy się konfigurowaniem wielu zbędnych rzeczy (lub odwoływanie się do pętli do iteracji w poprzek opcji grupowania, z powodu braku elegancji rozwiązanie).dplyr: colSums w podgrupach (group_by) ramkach danych: elegancko

Przykład kodu:

countData <- sample(0:10, 2000, replace = TRUE) 
dates <- sample(seq(as.Date("2010/1/1"), as.Date("2010/01/30"), "days"), 200, replace = TRUE) 
locality <- sample(1:2, 2000, replace = TRUE) 
ageCat <- sample(1:2, 2000, replace = TRUE) 
sampleDF <- data.frame(dates, locality, ageCat, matrix(countData, nrow = 200, ncol = 10)) 

to co chciałbym zrobić, to ...

library("dplyr") 
sampleDF %.% group_by(locality, ageCat, dates) %.% do(colSums(.[, -(1:3)])) 

ale to nie dość pracy, jak wynika z colSums() nie są ramkami danych. Jeśli go rzucę, działa:

sampleDF %.% group_by(locality, ageCat, dates) %.% do(data.frame(matrix(colSums(.[, -(1:3)]), nrow = 1, ncol = 10))) 

, ale końcowy fragment (...) wydaje się bardzo nieporęczny.

Jakieś przemyślenia na temat tego, jak to zrobić w bardziej elegancki lub skuteczny sposób? Chyba pytanie sprowadza się do: jak najlepiej korzystać z funkcji do() i. operator, aby podsumować ramkę danych za pomocą colSums.

Uwaga: operator do (.) Ma zastosowanie tylko do dplyr 0.2, więc musisz go pobrać z GitHub (link), a nie z CRAN.

EDIT: wynika z sugestii

trzy rozwiązania:

  1. moja propozycja na post: upłynęło, 146.765 sekund.

  2. @ sugestia Jøran jest poniżej: 6.902 sekund

  3. @ sugestią Eddi w komentarzach, używając data.table: 6.715 sek.

Nie zadałam sobie trudu replikowania, tylko użyłem system.time(), aby uzyskać przybliżoną grubość. Z jego wyglądu, dplyr i wykonują w przybliżeniu to samo na moim zbiorze danych, a oba są znacznie szybsze, gdy są używane właściwie niż rozwiązanie hackowe, które wymyśliłem wczoraj.

+0

Czy mógłbybyś podzielić się linkiem do miejsca, gdzie można dokładnie pobrać dplyr 0.2? Byłbym wdzięczny, że odkąd nie znalazłem pobierania na GitHub (i może to ułatwić innym członkom społeczności odpowiedź na twoje pytanie). –

+0

@beginneR Jeśli przejrzysz plik ReadMe na stronie github, zobaczysz polecenie instalacji z github. (Korzystanie z pakietu devtools). – joran

+0

@joran niesamowite, teraz instalacja .. dzięki za podpowiedź. –

Odpowiedz

8

chyba że jestem brakuje czegoś, wydaje się to zadanie dla summarise_each (rodzaj colwise analogowych z plyr):

sampleDF %.% group_by(locality, ageCat, dates) %.% summarise_each(funs(sum)) 

Kolumna grupowanie nie są zawarte w funkcji podsumowującej domyślnie i można wybrać tylko podzbiór kolumn, aby zastosować te funkcje do użycia tej samej techniki, co w przypadku korzystania z select.

(summarise_each jest w wersji 0.2 of dplyr ale nie w 0.1.3, o ile wiem.)

+0

Brakowało mi podsumowania: dzięki za sugestię! Jest znacznie szybszy niż wielokrotne przesyłanie, jak pokazuje edycja mojego oryginalnego wpisu. –

Powiązane problemy