2011-11-18 7 views
5

Muszę coś zrobić nie tak, ponieważ ta funkcja nie jest zakończona.Agregacja w celu utworzenia matrycy częstotliwości trwającej długo

Próbuję zebrać niektóre dane przez tydzień. Dane są podzielone na id i numer tygodniowy. Chciałbym, aby wynik miał id jako wiersze, tygodnie jako kolumny, a sumy jako wartości.

Przykład tego, co już próbowałem tak daleko (próbowałem kilka innych rzeczy, w tym dodanie zmiennej manekina = 1, a następnie fun.aggregating = suma nad tym):

ddply(data, .(id), dcast, id~weeknumber, value_var="id", 
     fun.aggregate=length, fill=0, .parallel=TRUE) 

Czy istnieje lepszy sposób to zrobić?

Wejście:

id  week 
1  1 
1  2 
1  3 
1  1 
2  3 

wyjściowa:

1 2 3 
1 2 1 1 
2 0 0 1 

Odpowiedz

10

Nie trzeba ddply do tego. dcast z reshape2 jest wystarczająca:

dat <- data.frame(
    id = c(rep(1, 4), 2), 
    week = c(1:3, 1, 3) 
) 

library(reshape2) 
dcast(dat, id~week, fun.aggregate=length) 

    id 1 2 3 
1 1 2 1 1 
2 2 0 0 1 

Edit: Do roztworu zasady R (innych niż table - jak pisał Joshua Uhlrich), spróbuj xtabs:

xtabs(~id+week, data=dat) 

    week 
id 1 2 3 
    1 2 1 1 
    2 0 0 1 
12

Mogłeś wystarczy użyć polecenia table:

table(data$id,data$week) 

    1 2 3 
    1 2 1 1 
    2 0 0 1 
+0

+1 Blast. Masz talent do tego, aby moje rozwiązania wyglądały na całkowicie rozwlekłe, okrągłe i piesze. – Andrie

+2

Jeśli masz dużo danych i operacji, których nie można tak bardzo uprościć, może ci pomóc pakiet "data.table". –

6

Powodem, dla którego ddply zajmuje tak dużo czasu, jest to, że podział według grupy nie jest wykonywany równolegle (tylko obliczenia na "podziałach"), więc z dużą liczbą grup będzie on wolny (i .parallel = T) nie pomoże .

Podejście to powinno być niezwykle wydajne pod względem czasu i pamięci.

Dla data.table efektywności najlepiej jest pracować w długi postaci zrobić grupowanie i następnie przekształcić do szerokiej

library(data.table) 
library(reshape2) 
DT <- data.table(data) 

setkeyv(DT, 'id') 

dcast(DT[, .N, by = list(id, week)], id~ week, fill = 0) 
Powiązane problemy