2017-02-09 1 views
1

Я могу реализовать прокатное окно, многократно меняя мои данные, а затем суммируя «row-wise», но это кажется громоздким и не просто обобщенным для разных размеров окон.Реализация катящегося окна с использованием data.table

#' Generate dummy data 
library(data.table) 
set.seed(42) 
d <- data.table(id=rep(letters[1:2], each=5), time=rep(1:5,times=2), x=sample.int(10,10,replace=T)) 

Данные выглядит следующим образом:

id time x 
a 1 10 
a 2 10 
a 3 3 
a 4 9 
a 5 7 
b 1 6 
b 2 8 
b 3 2 
b 4 7 
b 5 8 

Теперь возьмите качению 'максимум' в течение последних 2-х раз (для каждого идентификатора).

#' Now you want to take the maximum of the previous 2 x values (by id) 
#' I can do this by creating shifted lagged versions 
d[, x.L1 := shift(x,1,type='lag'), by=id] 
d[, x.L2 := shift(x,2,type='lag'), by=id] 
d[, x.roll.max := max(x,x.L1,x.L2, na.rm=2), by=.(id,time)] 

Формирует это

id time x x.L1 x.L2 x.roll.max 
a 1 10 NA NA 10 
a 2 10 10 NA 10 
a 3 3 10 10 10 
a 4 9 3 10 10 
a 5 7 9 3 9 
b 1 6 NA NA 6 
b 2 8 6 NA 8 
b 3 2 8 6 8 
b 4 7 2 8 8 
b 5 8 7 2 8 

Я предполагаю, что есть гораздо лучше.

+0

Возможно, посмотрите на различные функции 'roll *' в пакетах ** zoo ** и ** RcppRoll **. –

+0

@ JoshO'Brien: извините, фиксированные данные. Я видел сообщения с использованием зоопарка и RcppRoll, но подумал, что это будет то, что должно хорошо работать в data.table. – drstevok

+1

Ваш код упрощает 'd [, do.call (pmax, c (shift (x, 0: 2, type = 'lag'), na.rm = TRUE)), by = id]', но я предполагаю, что это по-прежнему менее эффективен, чем специализированный ролик, такой как RcppRoll. – Frank

ответ

0

Мне нравится пакет TTR Ульриха. Ниже дает бегущий макс

TTR::runMax(d$x,2) 
+0

Хороший отзыв о TTR, который работает красиво, но (к сожалению) не обрабатывает отсутствующие значения (опция 'na.rm = T') – drstevok

2

Так я последовал за @Franks suggestiong выше и пошел RcppRoll.

library(Rcpp) 
d[, x.roll.max := roll_max(x, n=2L, align='right', fill=NA, na.rm=T), by=id] 

И я предполагаю, что я не пытался сделать все это в data.table б/с это работает очень хорошо.

id time x x.roll.max 
a 1 11 NA 
a 2 12 12 
a 3 4 12 
a 4 10 10 
a 5 8 10 
a 6 7 8 
b 1 9 NA 
b 2 2 9 
b 3 8 8 
b 4 9 9 
b 5 6 9 
b 6 9 9 
+0

Примечание:' library (Rcpp) ' во-первых, потому что я получал следующую ошибку 'function 'enterRNGScope', которая не была предоставлена ​​пакетом 'Rcpp'', который, как я предполагал, означал, что функция из' Rcpp' маскируется с помощью data.table (см. http://stackoverflow.com/ вопросы/21657575/что-делает-это-среднее-в-lme4-функция-DataPtr-не-при условии, по-пакет-rcpp # 23020525) – drstevok

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