我一直在使用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
答案 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