在没有循环或使用pkg:gregmisc中的“running”的时间序列中滚动十进制排名

时间:2014-06-08 01:24:03

标签: r time-series ranking

我一直在使用gregmisc库来执行滚动十分位数排名。

我们说我有矢量' X' 1000连续值,我应用我的功能与250的回顾窗口(这是我使用的)。

我目前的功能如下: 前250个记录将是介于1和1之间的值。 10。 然后下一个记录251将由c(2:251)中的值确定,然后重复c(3:252)等...

虽然它比循环更快,但使用gregmisc"运行"我的十分位数功能的功能有很多不足之处。

我一直致力于通过在整个时间序列中操作来加速我的功能,通过创建我当时需要的基本信息列,但我没有像我这样提出类似的解决方案来解决这个问题。有其他人。当我使用这种方法时,我将处理时间缩短了95%。

矩阵可能会更快地运行,但我还没有看到它完好无损地击败我的正在运行的版本。

有什么想法吗?

谢谢!


以下是我使用的代码:1核心函数,然后是使用Greg misc滚动的函数:

F_getDecileVal <- function( x, deciles=0.1) {
    len<-length(x)
    y <- array(0,dim=len)   
    deciles <- seq(0,1,deciles)
    decileBounds <- quantile( x ,deciles, na.rm=TRUE)
        lendecile <- length(decileBounds)                  
        for( i in 2 : lendecile) {
            y[ which( x <= decileBounds[[i]] & x >= decileBounds[[i-1]] ) ] <- (i - 1)
        }   
    #Reverse Order so top decile has largest values
    dec6 <- which(y==6); dec7 <- which(y==7); dec8 <- which(y==8); dec9 <- which(y==9); dec10 <-which(y==10);
    dec1 <- which(y==1); dec2 <- which(y==2); dec3 <- which(y==3); dec4 <- which(y==4); dec5 <-which(y==5);
    y[dec1]<-10; y[dec2]<-9; y[dec3]<-8; y[dec4]<-7; y[dec5]<-6; y[dec6]<-5; y[dec7]<-4; y[dec8]<-3; y[dec8]<-3; y[dec9]<-2; y[dec10]<-1;

    return(y)
}

滚动功能:

F_getDecileVal_running <- function(x, decilecut=0.1,interval){
    len<-length(x)
      #Modified by ML 5/4/2013
      y <- array(NA, dim=len)
    if(len >= interval){
        y <- running(x, fun=F_getDecileVal, width=interval,records=1, pad=TRUE,simplify=TRUE)   
        y[1:interval] <- F_getDecileVal(x[1:interval])
    }
    return(y)
}
# system.time(F_getDecileVal_running(mydata[,8],interval=250))
# > dim(mydata)
# [1] 5677    9
#user  system elapsed 
#   4.28    0.00    4.38 

2 个答案:

答案 0 :(得分:2)

如果您可以接受使用&#39; decile&#39;这不是R的分位数函数中默认使用的那个(但是我认为类型= 6的可能选择之一),那么你可以只使用sort并提取第26,51,76 ,...等到第226或第250项,取决于你是否也想要最小和最大而不是内部十分位数&#34;铰链&#34;。 zoo-package中的rollapply函数是为滚动函数应用程序设计的,我认为从长远来看可能比gregmisc::running更有用,因为它是时间序列函数套件的一部分。这个更小的例子只返回一个简单集合的最小值,最大值和中值:

x <- 1:1000
require(zoo)
rollapply(x[1:300], 250, function(x) sort(x)[ c(1, 125, 250) ] )
      [,1] [,2] [,3]
 [1,]    1  125  250
 [2,]    2  126  251
 [3,]    3  127  252
 [4,]    4  128  253
 [5,]    5  129  254
 [6,]    6  130  255
 [7,]    7  131  256
 snipped the rest of the 50 lines of the output matrix.

答案 1 :(得分:1)

rolling_decile <-  function(i, v, window){
  v_s  <- v[i:(i + window - 1)]
  deciles <- cut(v_s,  
                 breaks = quantile(v_s, probs = seq(0, 1, by=0.1)),  
                 include.lowest = TRUE,
                 labels = 1:10)
  }

get_deciles  <- function(x, window){
        l  <- lapply(1:(length(x) - window + 1), rolling_decile, x, window)
        v  <- c(l[[1]], unlist(lapply(2:length(l), function(x) l[[x]][window])))
        }

x <- 1:1000
window <- 250 
d <-  get_deciles(x, window)

鉴于您的问题不确定您当前的功能有多快:

library(microbenchmark)
microbenchmark( 
  FUN = {
        get_deciles(x, window)
        })

#Unit: milliseconds
# expr      min       lq   median      uq     max neval
#  FUN 233.0379 242.6611 246.1712 249.682 309.985   100