Investr包与dplyr mutate配合时的异常行为
校准曲线逆估计结果不一致问题解析
问题背景与现象
我正在开发分析化学领域的校准曲线对比脚本,拥有自变量exp_conc(校准溶液浓度)和检测器响应值,构建了线性、二次及不同加权的模型。为了统一处理所有模型的逆估计(包括后续自动选择的模型),我使用了Investr包,但遇到了结果不一致的问题:
- 手动计算的
conc_1、循环逐个计算的conc_3结果一致且正确 - 通过
mutate调用自定义函数inwers_est得到的conc_2所有值都相同,与前两者结果不同
复现代码
library(tidyverse) library(investr) inwers_est <- function(model, response) { a <- invest(object = model, y0 = response, upper = 450, lower = -20) a <- unname(unlist(a[1])) return(a) } exp_conc <- c(1, 4, 15, 35, 70, 130, 220, 300, 400) response <- c(0.002793995, 0.010526501, 0.039554726, 0.094275798, 0.199609618, 0.366600791, 0.736514866, 0.918911425, 1.275848925) samp <- data.frame(exp_conc, response) regnwl <- lm(response ~ exp_conc, data = samp) samp <- samp %>% mutate( conc_1= (response-regnwl$coefficients["(Intercept)"]) /regnwl$coefficients["exp_conc"], conc_2 = inwers_est(regnwl, response)) for (ziutek in 1:nrow(samp)) { samp$conc_3[ziutek] <- inwers_est(regnwl, samp$response[ziutek]) }
问题根源
investr包的invest()函数不支持向量形式的y0输入。当传入整个response向量时,它只会对整个向量执行一次逆估计计算,返回单一值,而非逐个处理每个元素。这就是conc_2所有值相同的原因——它重复使用了单次计算的结果。
而循环中是逐个传入单个response值,invest()能正确处理单个数值输入,返回对应估计值;手动计算的conc_1则直接用线性模型的解析公式,自然能得到正确的逐元素结果。
解决方案
修改inwers_est函数,用purrr::map_dbl()实现向量化处理,逐个计算每个响应值对应的逆估计:
inwers_est <- function(model, response) { purrr::map_dbl(response, function(y) { a <- invest(object = model, y0 = y, upper = 450, lower = -20) unname(unlist(a[1])) }) }
修改后重新运行mutate代码,conc_2就会和conc_1、conc_3结果完全一致。
补充说明
线性模型的逆估计可以用解析公式直接计算,但Investr包的优势在于能处理非线性模型(如二次模型)的逆估计。修改后的函数既保留了Investr的通用性,又适配了tidyverse的向量化操作风格,能满足后续自动选择模型的需求。
内容的提问来源于stack exchange,提问作者Radek Jaźwiec
相关产品推荐
相关产品推荐

