假设我们有一个具有数百个线性模型参数的 DF,包括斜率 m 和 y 轴截距 b,以及积分上限 up_lim。
tmp_df <- tibble(m = rnorm(1:1000, mean = 1, sd = 1),
b = rnorm(1:1000, mean = 3, sd = 0.5),
up_lim = rnorm(1:1000, mean = 11, sd = 4))
我的目标是使用简单的线性模型在 x 上进行行积分,从0到up_lim:
integrand <- function(x) { m * x + b }
结果应存储在 tmp_df 中的新列中。我在网上进行了一些搜索,我知道
integrate
函数的非矢量性质,但无法将我找到的任何讨论/解决方案转化为我的案例。我最好的解决方案是循环,它适用于几百个集成,但当我向它提供完整的数据集(> 100 万行)时,它会导致我的 12 核 MacBook 崩溃(即使在我尝试了多核支持之后):
lapply(c("foreach", "doParallel"),
library, character.only = TRUE)
n <- nrow(tmp_df)
registerDoParallel(numCores)
tmp_df$Fs_linear <-
foreach (i = 1:n, .combine = rbind) %dopar% {
integrate(
function(x) { tmp_df$m[i] * x + tmp_df$b[i] },
lower = 0,
upper = tmp_df$up_lim[i])$value
}
stopImplicitCluster()
有没有一种优雅/资源高效的方法来实现这一点?我将非常感谢任何指点。
m*x+b
相对于x
的积分,从x=0
到x=u
,只是在(m*x^2/2 + b*x)
和x=u
处评估的x=0
之差,即m*u^2+b*u
。 (测试:
f = function(x, m=3, b=1) m*x +b
integrate(f, lower = 0, upper = 5)
## 42.5 with absolute error < 4.7e-13
3*5^2/2 + 1*5 ## also 42.5
所以
dplyr::mutate(tmp_df, Fs_linear = m*up_lim^2/2 + b*up_lim)
应该可以工作(
system.time()
说这需要大约0.001秒,我没有打扰microbenchmark
...)