在 mapply 调用中使用多行

Using multiple rows in a mapply call

这似乎是一个简单的问题,但我在 Stack Overflow 上找不到解决方案。我有一个数据框 df,其中包含数据列 ab。我有一个复杂的函数(下面的简化示例),我想使用 mapply 将其应用于所有行。我遇到的问题是我想取 bnn-1 行的平均值作为函数的输入,而不是 b。这是一个例子

new.fun  <- function( a, b ) { a * b } 
a        <- seq( from = 1, to = 10, by = 1 )
df       <- data.frame( a , b = a * 10 ) 
mapply( new.fun, df$a, df$b )

缺少使用 nn-1 的平均值创建新列(我只知道如何使用 for 循环)并将其用作输入,或者创建一个 for 循环,有没有办法以更 "R-like" 的方式做到这一点?

编辑:抱歉,我忘了为上面的例子添加预期的答案。 b[1:2]b[2:3]等的平均值应该是:

 b2   <- c( 0, seq( from = 15, to = 95, by = 10 ) )

EDIT2:此处的项数错误....出于这些目的将第一项设置为 0

整个问题的答案应该是:

> new.fun( df$a, b2 )
 [1]   0  30  75 140 225 330 455 600 765 950

对于这里令人困惑的一系列帖子,我们深表歉意。显然我没有准确描述问题。我希望 mapply 调用中的一个变量不包含 df 列的特定行中的值,而是 nth 行和 n-1 行的平均值] 行,基本上是该行和前一行的移动平均值,但我想知道它是否可以以某种巧妙的方式打包在 mapply 调用中?

lapply(seq(2, nrow(df)), function (i) {
  mean_a <- mean(df$a[(i-1):i])
  mean_b <- mean(df$b[(i-1):i])
  new.fun(mean_a, mean_b)
})

如果您知道函数将要生成的输出长度,则可以使用 sapply

另见 zoo::rollapply

我们可以使用 zoo 包中的 rollmean 来计算 b 列的滚动平均值,然后将其与 a 列相乘。 (类似于@Sotos在评论中提到的内容。)

library(zoo)
df$a * c(0, rollmean(df$b, 2))

#[1]  0 30  75 140 225 330 455 600 765 950

或者使用mapply函数

mapply(new.fun, df$a, c(0, rollmean(df$b, 2))

zoo::rollapply 是针对轻量级问题的非常重量级(且缓慢)的解决方案。

with(df, {
    bmean <- c(NA, (b[-1] + b[-length(b)])/2)  # replace NA with desired initial value
    mapply(new.fun, a, bmean)
})