在“窗口”中使用apply

时间:2013-12-16 06:42:49

标签: r apply

有没有办法在'windows'或'range'上使用apply函数?这个例子应该用来说明:

a <- 11:20

现在我想计算连续元素的总和。即。

[11 + 12,12 + 13,13 + 14,...]

我能想到的处理方法是:

a <- 11:20
b <- NULL
for(i in 1:(length(a)-1))
{
    b <- c(b, a[i] + a[i+1])
}
# b is 23 25 27 29 31 33 35 37 39

或者,

d <- sapply( 1:(length(a)-1) , function(i) a[i] + a[i+1] )
# d is 23 25 27 29 31 33 35 37 39

有更好的方法吗? 我希望有类似的东西:

e <- windowapply( a, window=2, function(x) sum(x) )  # fictional function
# e should be 23 25 27 29 31 33 35 37 39

3 个答案:

答案 0 :(得分:4)

这是使用动物园包

中的rollapply的替代方案
> rollapply(a, width=2, FUN=sum )
[1] 23 25 27 29 31 33 35 37 39

zoo包还提供rollsum功能

> rollsum(a, 2)
[1] 23 25 27 29 31 33 35 37 39

答案 1 :(得分:4)

我们可以定义一般的moving()函数:

moving <- function(f){
  g <- function(i , x, n , f, ...) f(x[(i-n+1):i], ...)
  function(x, n, ...) {
    N <- length(x)
    vapply(n:N, g, x , n , f, FUN.VALUE = numeric(1), ...)
  }  
}

函数moving()返回的函数又可用于生成任何moving_f()函数:

moving_sum <- moving(sum)  
moving_sum(x = 11:20, n = 2)

同样,甚至将额外的参数传递给moving_f()

moving_mean <- moving(mean)  
moving_mean(x = rpois(22, 6), n = 5, trim = 0.1)

答案 2 :(得分:0)

您可以通过首先创建索引列表然后windowapply来实现*apply函数,以便将它们用作提取索引:

j <- lapply(seq_along(a), function(i) if(i<10) c(i,i+1) else i)
sapply(j, function(j) sum(a[j]))
## [1] 23 25 27 29 31 33 35 37 39