2014-09-08 2 views
2

У меня есть кадр данных, содержащий количество просмотров страниц на пользователя в неделю. Я хочу определить для каждого пользователя, увеличивались ли их взгляды, уменьшались или оставались неизменными после определенного события. Мои данные выглядит следующим образом:Сравните со следующей строкой, сгруппированы, data.table

Userid week xeventinweek numviews 
Alice 1 2   5 
Alice 2 0   3 
Alice 4 1   6 
Bob  2 2   3 
Bob  3 0   5 

Таким образом, в этом случае, вид Алисы уменьшилось после того, как она была 2 события в 1-й недели, и у нее не было никаких событий в 2 недели, чтобы измерить. Однако Боб увеличил свои взгляды с 3 по 5 неделю после того, как у него было два события.

Я хотел бы получить таблицу с разницей в мнениях на каждую неделю, в которой было хотя бы одно событие. Так оно и должно выглядеть примерно так:

Userid week xeventinweek numviews numnextweek difference 
Alice 1  2   5   3    -2 
Alice 4  1   6   NA    NA #the row for week 2 is missing because there were no events then for Alice 
Bob  2  2   3   5    2 

Это не важно иметь как numnextweek и разностные столбцы - либо или в порядке.

Я смог сделать это, используя data.table и цикл for, но потребовалось так много времени, чтобы выполнить, что это было невозможно. Я думал о том, чтобы использовать скользящее соединение, но это не представляется возможным сгруппированными данными (т. Е. Это нужно будет делать индивидуально для каждого пользователя.) Как это сделать, используя собственную функциональность data.table?

ответ

3

Использование match:

dat[, numnextweek := numviews[match(week + 1, week)] , by=Userid] 
dat[, difference := numviews - numnextweek , by=Userid] 
dat[xeventinweek != 0] 

# Userid week xeventinweek numviews numnextweek difference 
#1: Alice 1   2  5   3   2 
#2: Alice 4   1  6   NA   NA 
#3: Bob 2   2  3   5   -2 
+0

это работает - благодаря! – bsg

1

Начиная с версии v1.9.6 (на CRAN 19 сен 2015), функция shift() доступна в data.table:

DT[, difference := shift(numviews, type = "lead") - numviews, by = Userid][ 
    xeventinweek != 0L] 
Userid week xeventinweek numviews difference 
1: Alice 1   2  5   -2 
2: Alice 4   1  6   NA 
3: Bob 2   2  3   2 
+0

Я думаю, вы должны проверять неделю + 1L (возможно, на соединение), а не только на следующую строку. Очевидно, что у ПП отсутствуют недели. Я имею в виду 'DT [. (U = Userid, w = week + 1L, numviews = numviews), on =. (Userid = u, week = w), i.numviews - x.numviews]' больше похоже на thela. – Frank

+0

@Frank Я думаю, вы правы. К сожалению, пропавшая неделя 3 - это право после недели 2 без события, которое в любом случае не должно быть показано. Таким образом, только из ожидаемого результата мы не можем быть на 100% уверены, как OP хочет иметь дело с отсутствующими неделями. – Uwe

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