2015-01-18 11 views
8

Próbuję utworzyć funkcję okna z dplyr, która zwróci nowy wektor z różnicą między każdą wartością a pierwszą z jej grupy. Na przykład, biorąc pod uwagę ten zbiór danych:różnica od pierwszego w grupie z dplyr

dummy <- data.frame(userId=rep(1,6), 
    libId=rep(999,6), 
    curatorId=c(1:2,1:2,1:2), 
    iterationNum=c(0,0,1,1,2,2), 
    rf=c(5,10,0,15,30,40) 
) 

To tworzy ten zestaw danych:

userId libId curatorId iterationNum rf 
1  1 999   1   0 5 
2  1 999   2   0 10 
3  1 999   1   1 0 
4  1 999   2   1 15 
5  1 999   1   2 30 
6  1 999   2   2 40 

A biorąc pod uwagę tego ugrupowania:

dummy<-group_by(dummy,libId,userId,curatorId) 

dałby ten wynik:

userId libId curatorId iterationNum rf rf.diff 
1  1 999   1   0 5 0 
2  1 999   2   0 10 0 
3  1 999   1   1 0 -5 
4  1 999   2   1 15 -5 
5  1 999   1   2 30 25 
6  1 999   2   2 40 30 

Tak więc dla każdej grupy użytkowników, bibliotek i kuratorów, otrzymam wartość rf, minus wartość rf z iteracjąNumer = 0. Próbowałem odtwarzać za pomocą funkcji first, funkcji rank i innych, ale nie mogłem znaleźć sposobu jej utrwalenia.

--- EDIT ---

To co próbowałem:

dummy %>% 
    group_by(userId,libId,curatorId) %>% 
    mutate(rf.diff = rf - subset(dummy,iterationNum==0)[['rf']]) 

oraz:

dummy %>% 
    group_by(userId,libId,curatorId) %>% 
    mutate(rf.diff = rf - first(x = rf,order_by=iterationNum)) 

Który rozbija R i zwraca ten komunikat o błędzie:

pure virtual method called terminate called after throwing an instance of 'Rcpp::exception' what(): incompatible size (%d), expecting %d (the group size) or 1`

+0

Wygląda na to, że znasz już wszystkie funkcje potrzebne do wykonania tej czynności. Czy możesz pokazać, co wypróbowałeś i co nie działało zgodnie z oczekiwaniami? Być może po prostu musisz uporządkować (zamówić) swoje dane przed obliczeniem różnic. –

+1

Byłeś blisko. Zamiast tego użyj 'rf - rf [iterationNum == 0]' wewnątrz mutacji. Inną opcją jest ułożenie danych za pomocą 'arran (iterationNum)' jako oddzielnego kroku w rurze i użycie 'rf - first (rf)' w mutacie, jeśli jesteś pewien, że każda grupa ma 0 w rf i nie niższe wartości. –

+0

'rf - first (rf, iterationNum)' – hadley

Odpowiedz

5

Dwa podejścia, które skomentowałem powyżej są następujące.

dummy %>% 
    group_by(libId, userId, curatorId) %>% 
    mutate(rf.diff = rf - rf[iterationNum == 0]) 
#Source: local data frame [6 x 6] 
#Groups: libId, userId, curatorId 
# 
# userId libId curatorId iterationNum rf rf.diff 
#1  1 999   1   0 5  0 
#2  1 999   2   0 10  0 
#3  1 999   1   1 0  -5 
#4  1 999   2   1 15  5 
#5  1 999   1   2 30  25 
#6  1 999   2   2 40  30 

lub używając arrange zamówić dane przez iterationNum:

dummy %>% 
    arrange(iterationNum) %>% 
    group_by(libId, userId, curatorId) %>% 
    mutate(rf.diff = rf - first(rf)) 
#Source: local data frame [6 x 6] 
#Groups: libId, userId, curatorId 
# 
# userId libId curatorId iterationNum rf rf.diff 
#1  1 999   1   0 5  0 
#2  1 999   2   0 10  0 
#3  1 999   1   1 0  -5 
#4  1 999   2   1 15  5 
#5  1 999   1   2 30  25 
#6  1 999   2   2 40  30 

Jak widać, oba wytwarzają taką samą moc dla przykładowych danych.

Powiązane problemy