2015-01-18 3 views
8

Я пытаюсь создать функцию окна с dplyr, которая вернет новый вектор с разницей между каждым значением и первым его группой. Например, если этот набор данных:отличие от первого в группе с 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) 
) 

Это создает этот набор данных:

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 

И учитывая эту группировку:

dummy<-group_by(dummy,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 

Поэтому для каждой группы пользователей, библиотек и кураторов я получаю значение rf, минус значение rf с помощью iterationNum = 0. Я пробовал играть с функцией first, функцией rank и другими, но не смог найти способ прибить ее.

--- EDIT ---

Это то, что я пробовал:

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

И:

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

Какой сбой R и возвращает сообщение об ошибке:

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

Кажется, что вы уже знаете все функции, необходимые для этого. Можете ли вы показать, что вы пытались и что не сработало, как ожидалось? Возможно, вам просто нужно упорядочить (упорядочить) свои данные перед вычислением различий. –

+1

Вы были рядом. Вместо этого используйте 'rf - rf [iterationNum == 0]' внутри мутанта. Другой вариант состоит в том, чтобы упорядочить данные с помощью 'organiz (iterationNum)' как отдельного шага в канале и использовать 'rf - first (rf)' в мутате, если вы уверены, что каждая группа имеет 0 в rf и нет более низкие значения. –

+0

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

ответ

5

Два подхода, которые я прокомментировал выше, являются следующими.

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 

Или с помощью arrange заказать данные по 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 

Как вы можете видеть, как производить тот же вывод для выборки данных.

Смежные вопросы