Суммарная сумма с отставанием

У меня есть очень большой набор данных, который выглядит упрощенно следующим образом:

row.    member_id   entry_id    comment_count   timestamp
1       1            a              4           2008-06-09 12:41:00
2       1            b              1           2008-07-14 18:41:00
3       1            c              3           2008-07-17 15:40:00
4       2            d              12          2008-06-09 12:41:00
5       2            e              50          2008-09-18 10:22:00
6       3            f              0           2008-10-03 13:36:00

Я могу агрегировать счетчики с помощью следующего кода:

transform(df, aggregated_count = ave(comment_count, member_id, FUN = cumsum))

Но я хочу, чтобы в накопленных данных было отставание 1, или я хочу, чтобы cumsum игнорировал текущую строку. Результат должен быть:

row.    member_id   entry_id     comment_count  timestamp             previous_comments
1       1            a              4           2008-06-09 12:41:00        0
2       1            b              1           2008-07-14 18:41:00        4
3       1            c              3           2008-07-17 15:40:00        5
4       2            d              12          2008-06-09 12:41:00        0
5       2            e              50          2008-09-18 10:22:00        12
6       3            f              0           2008-10-03 13:36:00        0

Некоторая идея, как я могу сделать это в R? Может быть, даже с отставанием больше 1?


Данные для воспроизводимости:

# dput(df)
structure(list(member_id = c(1L, 1L, 1L, 2L, 2L, 3L), entry_id = c("a", 
"b", "c", "d", "e", "f"), comment_count = c(4L, 1L, 3L, 12L, 
50L, 0L), timestamp = c("2008-06-09 12:41:00", "2008-07-14 18:41:00", 
"2008-07-17 15:40:00", "2008-06-09 12:41:00", "2008-09-18 10:22:00", 
"2008-10-03 13:36:00")), .Names = c("member_id", "entry_id", 
"comment_count", "timestamp"), row.names = c("1", "2", "3", "4", 
"5", "6"), class = "data.frame")

person Nikolas    schedule 25.12.2014    source источник
comment
Кажется, вы уже написали правильный код в предложении, подсказка подсказка :)   -  person Rich Scriven    schedule 25.12.2014


Ответы (3)


Вы можете использовать 0 для первого элемента и удалить последний элемент, используя head(, -1)

transform(df, previous_comments=ave(comment_count, member_id, 
          FUN = function(x) cumsum(c(0, head(x, -1)))))
#  member_id entry_id comment_count           timestamp previous_comments
#1         1        a             4 2008-06-09 12:41:00                 0
#2         1        b             1 2008-07-14 18:41:00                 4
#3         1        c             3 2008-07-17 15:40:00                 5
#4         2        d            12 2008-06-09 12:41:00                 0
#5         2        e            50 2008-09-18 10:22:00                12
#6         3        f             0 2008-10-03 13:36:00                 0
person GSee    schedule 25.12.2014
comment
Работает идеально. Спасибо и с Рождеством :) ! - person Nikolas; 26.12.2014

Вы можете использовать lag из dplyr и изменить k

library(dplyr)
df %>% 
    group_by(member_id) %>%
    mutate(previous_comments=lag(cumsum(comment_count),k=1, default=0))
 #    member_id entry_id comment_count           timestamp previous_comments
 #1         1        a             4 2008-06-09 12:41:00                 0
 #2         1        b             1 2008-07-14 18:41:00                 4
 #3         1        c             3 2008-07-17 15:40:00                 5
 #4         2        d            12 2008-06-09 12:41:00                 0
 #5         2        e            50 2008-09-18 10:22:00                12
 #6         3        f             0 2008-10-03 13:36:00                 0

Или используя data.table

 library(data.table)
  setDT(df)[,previous_comments:=c(0,cumsum(comment_count[-.N])) , member_id]
person akrun    schedule 25.12.2014

Просто вычтите comment_count из ave :

transform(df, 
  aggregated_count = ave(comment_count, member_id, FUN = cumsum) - comment_count)
person G. Grothendieck    schedule 25.12.2014