开发者

Rolling apply to subset of a vector

开发者 https://www.devze.com 2023-04-09 19:35 出处:网络
I want to apply a function to progressive subsets of a vector in R. I have looked at what i could find, and the apply and friends aren\'t quite there, and rollapply does not work on straight vectors,

I want to apply a function to progressive subsets of a vector in R. I have looked at what i could find, and the apply and friends aren't quite there, and rollapply does not work on straight vectors, only zoo/ts 开发者_运维问答objects.

vapply <- function(x, n, FUN=sd) {
    v <- c(rep(NA, length(x)))
    for (i in n:length(x) ) {  
        v[i] <- FUN(x[(i-n+1):i])
    }
    return(v)
}

Is there something built in that is equivalent? Is there a better way to do it? I am trying to avoid dependencies on 3rd party libraries as I the code needs to be standalone for distribution.


With your choice of function name, I just HAD to make a version that actually uses vapply internally :) ...it turns out to be about 50% faster in the example below. But that of course depends a lot on how much work is done in FUN...

# Your original version - renamed...
slideapply.org <- function(x, n, FUN=sd) {
    v <- c(rep(NA, length(x)))
    for (i in n:length(x) ) {  
        v[i] <- FUN(x[(i-n+1):i])
    }
    return(v)
}

slideapply <- function(x, n, FUN=sd, result=numeric(1)) {
    stopifnot(length(x) >= n) 
    FUN <- match.fun(FUN)
    nm1 <- n-1L
    y <- vapply(n:length(x), function(i) FUN(x[(i-nm1):i]), result)

    c(rep(NA, nm1), y) # Why do you want NA in the first entries?
}

x <- 1:2e5+0 # A double vector...
system.time( a <- slideapply.org(x, 50, sum) )  # 1.25 seconds
system.time( b <- slideapply(x, 50, sum) )      # 0.80 seconds
identical(a, b) # TRUE
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号