【发布时间】:2018-01-24 20:39:15
【问题描述】:
如果我正在使用的值是与前 30 个值相比的异常值,我需要计算 ts。 我正在使用的数据的维度为 600 列 x 200000 行。所以我想利用数据表速度的好处。
我的功能是:
es_outlier<-function(vect){
qq =quantile(vect, prob=c(0.25,0.75), na.rm=T)
q3=qq[2]
IC=q3-qq[1]
limSup=q3+IC*1.5
vector_final=abs(vect)>limSup
return(vector_final[length(vect)] )
}
一个示例表是:
library(data.table)
dt<-data.table(x1=runif(50000), x2=runif(50000))
dt$x1[555]<-2000
dt$x2[556]<-2000
我可以用 zoo 包解决这个问题:
zoo::rollapply(dt,30,es_outlier, fill=NA,align='right')
但这需要很多时间,而且比我的真实数据要少。
我想要类似的东西:
dt[, (nom):=lapply(.SD,function, n=30)]
我尝试使用 Rcpp,但它没有分位数功能。
有没有更快的方法来应用我的功能?
PS:对于一个小表,函数返回:
x<-data.frame(x1=1:8, x2=c(1:7,2000))
x_dt<-data.table(x)
zoo::rollapply(x_dt,5,es_outlier, fill=NA,align='right')
x1 x2
NA NA
NA NA
NA NA
NA NA
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE TRUE
【问题讨论】:
-
能否复制行并分配组,即g1=1:30、g2=2:31等,然后在数据表中按组执行
es_outlier? -
@rawr,我猜......它需要更少的时间吗?我是数据表的新手,所以我不知道该怎么写。
-
我不确定,你有几个瓶颈:你的函数、数据的大小和rollapply。 data table 应该可以减少数百万行的大小,并且函数没有改变,所以如果你堆叠数据,似乎可以消除 rollapply 的一个瓶颈?
-
你也可以通过只调用一次
quantile来稍微提高你的函数的速度(并且你不使用中值,所以你也可以摆脱它)eso2 <- function(v) {x <- quantile(v, c(.25, .75), na.rm = TRUE); l <- x[2L] + (x[2L] - x[1L]) * 1.5; (abs(v) > l)[length(v)]}跨度> -
分析您的代码并检查大部分时间是否在
es_outlier。如果是这样,那么将其包装在 data.table 之类的其他内容中将无济于事。