R语言自定义函数内拟合lm模型指定响应变量报非数值参数错误
R自定义lm拟合函数动态传参报错修复方案
核心报错原因
两个版本代码的报错来自几处明确的语法和逻辑问题:
- 初始版本直接在
lm()公式中写log(parameter)时,R会默认parameter是数据集里的固定列名,不会自动识别为传入的函数参数:传入带引号的字符串时,字符串无法参与对数运算,触发non-numeric argument to mathematical function报错;传入不带引号的变量名时,函数环境中找不到对应独立对象,触发object 'myobject' not found报错。 - 更新版拼接公式时未将固定列名
flow写入字符串,R会在当前环境中搜索名为flow的独立对象,而非识别为数据集中的列,直接触发对象不存在报错。 - 初始版本构造预测流量序列时写错参数名:函数入参为
pred_maxflow、pred_flowint,代码中误写为maxflow、flowint,触发对象不存在报错。 - 额外逻辑隐患:流量值从0开始时
log(0)为负无穷,会导致线性模型拟合异常;使用<<-向全局环境超赋值preds属于坏实践,会意外覆盖全局同名对象;初始版构造测试数据时重复将第二列命名为parameter1_conc,会覆盖第一列的浓度数据。
修复后可直接运行的代码
# 加载依赖 library(tibble) # 构造测试数据集 flows <- seq(0.01,7,0.01) # 流量从0.01开始,避免log(0)的无穷值问题 dat <- tibble( flow = sample(flows, 30), parameter1_conc = rnorm(30, 15, 4), parameter2_conc = rnorm(30, 50, 8) ) # 修复后的回归预测函数 regr_func <- function(modeldata, parameter, pred_maxflow, pred_flowint) { # 正确拼接公式:动态响应变量拼入字符串,固定解释变量flow直接写在公式字符串中 mod <- lm(as.formula(paste0('log(', parameter, ') ~ log(flow)')), data = modeldata) # 构造预测用流量序列,匹配入参名 newflow <- data.frame(flow = seq(0.01, pred_maxflow, pred_flowint)) # 预测结果作为返回值输出,不修改全局环境 preds <- predict(mod, newdata = newflow, interval = 'prediction') # 绑定流量列返回,后续使用更方便 preds <- cbind(newflow, preds) return(preds) } # 函数调用示例 pred_result <- regr_func( modeldata = dat, parameter = 'parameter1_conc', pred_maxflow = 20, pred_flowint = 0.001 )
可选非字符串拼接实现方式
如果不想处理公式拼接的字符串问题,可以直接用数据框子集方式提取动态列,逻辑更稳妥:
regr_func <- function(modeldata, parameter, pred_maxflow, pred_flowint) { # 提前提取列做对数转换,不用拼公式 fit_data <- data.frame( y = log(modeldata[[parameter]]), x = log(modeldata[["flow"]]) ) mod <- lm(y ~ x, data = fit_data) # 构造预测数据 pred_flow_seq <- seq(0.01, pred_maxflow, pred_flowint) newdata <- data.frame(x = log(pred_flow_seq)) preds <- predict(mod, newdata = newdata, interval = 'prediction') preds <- cbind(flow = pred_flow_seq, preds) return(preds) }
内容的提问来源于stack exchange,提问作者dandrews
相关产品推荐
相关产品推荐

