[R data.table滑动窗口(R data.table sliding window)

2019-06-17 13:48发布

什么是最好的(最快)的方式来实现与data.table包滑动窗口的功能?

我试图计算的滚动中位数,但有每个日期多行(由于2个额外的因素),我认为这意味着动物园rollapply功能是行不通的。 下面是一个使用幼稚for循环的例子:

library(data.table)
df <- data.frame(
  id=30000,
  date=rep(as.IDate(as.IDate("2012-01-01")+0:29, origin="1970-01-01"), each=1000),
  factor1=rep(1:5, each=200),
  factor2=1:5,
  value=rnorm(30, 100, 10)
)

dt = data.table(df)
setkeyv(dt, c("date", "factor1", "factor2"))

get_window <- function(date, factor1, factor2) {
  criteria <- data.table(
    date=as.IDate((date - 7):(date - 1), origin="1970-01-01"),
    factor1=as.integer(factor1),
    factor2=as.integer(factor2)
  )
  return(dt[criteria][, value])
}

output <- data.table(unique(dt[, list(date, factor1, factor2)]))[, window_median:=as.numeric(NA)]

for(i in nrow(output):1) {
  print(i)
  output[i, window_median:=median(get_window(date, factor1, factor2))]
}

Answer 1:

data.table没有任何特殊功能,用于滚动窗口,目前。 这里更详细的我的答案在这里的另一个类似的问题:

是否有内运行data.table滚动回归的快捷方式?

滚动中位数是有趣的。 这将需要一个专门的功能,有效地完成(同一条链路在先前的评论):

滚动使用C的中值算法

data.table在问题解决方案和答案在这里都非常低效的,相对于适当的专业rollingmedian功能(这是不可用的R据我所知)。



Answer 2:

我设法通过创建一个滞后的数据集,并做了巨大的加入,以获得例如降低到1.4秒。

df <- data.frame(
  id=30000,
  date=rep(as.IDate(as.IDate("2012-01-01")+0:29, origin="1970-01-01"), each=1000),
  factor1=rep(1:5, each=200),
  factor2=1:5,
  value=rnorm(30, 100, 10)
)

dt2 <- data.table(df)
setkeyv(dt, c("date", "factor1", "factor2"))

unique_set <-  data.table(unique(dt[, list(original_date=date, factor1, factor2)]))
output2 <- data.table()
for(i in 1:7) {
  output2 <- rbind(output2, unique_set[, date:=original_date-i])
}    

setkeyv(output2, c("date", "factor1", "factor2"))
output2 <- output2[dt]
output2 <- output2[, median(value), by=c("original_date", "factor1", "factor2")]

这工作得很好,在这个测试数据集,但是,我真正的失败与8GB的内存。 我要去尝试移动到高端内存EC2实例的一个(17,34或68GB RAM)得到它的工作。 如何做到这一点的少内存密集型的方式任何想法,将不胜感激



Answer 3:

该解决方案的工作,但还需要一段时间。

df <- data.frame(
  id=30000,
  date=rep(seq.Date(from=as.Date("2012-01-01"),to=as.Date("2012-01-30"),by="d"),each=1000),
  factor1=rep(1:5, each=200),
  factor2=1:5,
  value=rnorm(30, 100, 10)
)

myFun <- function(dff,df){
    median(df$value[df$date>as.Date(dff[2])-8 & df$date<as.Date(dff[2])-1 & df$factor1==dff[3] & df$factor2==dff[4]])
}

week_Med <- apply(df,1,myFun,df=df)

week_Med_df <- cbind(df,week_Med)


文章来源: R data.table sliding window