对向量子集进行滚动应用

3

我希望在R中对向量的逐步子集应用函数。我查看了相关资料,发现apply及其相关函数并不完全符合要求,而rollapply仅适用于zoo/ts对象,而不能直接使用于向量。

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)
}

有没有类似的内置功能?是否有更好的方法实现?我试图避免依赖第三方库,因为代码需要独立分发。


你能给我们一些数据(和期望的结果)来进行测试吗? - Roman Luštrik
我建议你不要将其命名为vapply,因为这已经是一个广泛使用的函数名称(快速向量应用)。 - Andrie
2
这只是一个小问题,但我认为rollapply在原子向量上的使用还是没问题的,只不过它会先将其转换为 zoo 对象。所以,这仍然违反了您避免依赖项的要求。 - joran
关于您所期望的“独立运行”条件的评论:任何要使用您分发的R代码(或软件包)的人都不会在安装CRAN上可用的任何软件包方面遇到问题。但是,如果您真的很担心,只需将所需的库与您的分发一起包含 - 内置于您的软件包中,或作为您的zip / tarball /任何发行版的一部分。 - Carl Witthoft
joran我遇到了与这个rollapply(1:100, width=10, FUN=sd)相当的问题。Carl,这不是一个真正的障碍,但我不能假设它将在有网络连接的机器上使用,并且更愿意避免维护这种相对琐碎的依赖性。谢谢大家的阅读。 - dizzy
1个回答

3

看到你选择的函数名,我就不得不做一个实际上使用 vapply 的版本 :) ......结果在下面的示例中快了约50%。但这当然在很大程度上取决于 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

非常酷,谢谢!我想要额外的NA值,这样我就可以将它与现有的数据框进行列绑定。 - dizzy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接