在 mapply 调用中使用多行
Using multiple rows in a mapply call
这似乎是一个简单的问题,但我在 Stack Overflow 上找不到解决方案。我有一个数据框 df
,其中包含数据列 a
和 b
。我有一个复杂的函数(下面的简化示例),我想使用 mapply
将其应用于所有行。我遇到的问题是我想取 b
的 n
和 n-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 )
缺少使用 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
行和 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)
})
这似乎是一个简单的问题,但我在 Stack Overflow 上找不到解决方案。我有一个数据框 df
,其中包含数据列 a
和 b
。我有一个复杂的函数(下面的简化示例),我想使用 mapply
将其应用于所有行。我遇到的问题是我想取 b
的 n
和 n-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 )
缺少使用 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
行和 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)
})