这似乎是一个简单的问题,但我在Stack Overflow上找到解决方案时遇到了麻烦。我的数据框df
包含数据a
和b
列。我有一个复杂的函数(下面的简化示例),我想使用mapply
应用于所有行。我遇到的问题是,我希望将n
和n-1
行b
的平均值作为函数的输入,代替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 )
创建一个平均值为n
和n-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
行和{{1}的平均值行,基本上是行和前一行的移动平均线,但我想知道它是否可以以某种聪明的方式打包在n-1
调用中?
答案 0 :(得分: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)
})
答案 1 :(得分:1)
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
。
答案 2 :(得分:0)
我们可以使用rollmean
包中的zoo
来计算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))