You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言glm模型公式参数非标准求值问题求解

解决R中glm公式非标准求值导致call参数未替换i值的问题

在循环或迭代拟合多个logistic回归模型时,使用glm(mpg_20 ~ poly(horsepower, i), data = Auto)生成的模型对象,其call参数始终保留符号i,而非替换为迭代时的具体数值。以下是三种解决该非标准求值问题的实用方法:

方法1:用bquote()构造已求值的公式

bquote()可以将表达式中用.(变量)标记的部分替换为当前环境中的实际值,适合动态生成带参数的公式。

修改后的可复现代码:

# 加载数据
data("Auto", package = "ISLR2")

# 创建二分类响应变量
Auto$mpg_20 <- as.numeric(Auto$mpg < 20)

# 批量拟合模型
mlist <- lapply(
  1:3, 
  \(i) {
    # 构造替换了i值的公式
    eval_formula <- bquote(mpg_20 ~ poly(horsepower, .(i)))
    glm(eval_formula, data = Auto, family = binomial)
  }
)

# 查看模型call参数
lapply(mlist, \(x) x$call)

方法2:用reformulate()从字符串生成公式

reformulate()通过字符串拼接的方式构造公式,逻辑直观,尤其适合处理动态变化的项。

代码示例:

mlist <- lapply(
  1:3, 
  \(i) {
    # 拼接右侧项的字符串
    rhs_term <- sprintf("poly(horsepower, %d)", i)
    # 生成完整公式
    eval_formula <- reformulate(rhs_term, response = "mpg_20")
    glm(eval_formula, data = Auto, family = binomial)
  }
)

# 验证call参数
lapply(mlist, \(x) x$call)

方法3:事后修改模型的call参数

如果已经完成模型拟合,也可以直接修改模型对象的call部分,将符号i替换为具体数值:

mlist <- lapply(
  1:3, 
  \(i) {
    model <- glm(mpg_20 ~ poly(horsepower, i), data = Auto, family = binomial)
    # 替换call中的i为当前迭代值
    model$call$formula <- do.call(substitute, list(model$call$formula, list(i = i)))
    model
  }
)

# 查看修改后的call
lapply(mlist, \(x) x$call)

预期输出

以上三种方法运行后,都会得到符合预期的结果:

[[1]]
glm(formula = mpg_20 ~ poly(horsepower, 1), data = Auto, family = binomial)

[[2]]
glm(formula = mpg_20 ~ poly(horsepower, 2), data = Auto, family = binomial)

[[3]]
glm(formula = mpg_20 ~ poly(horsepower, 3), data = Auto, family = binomial)

注意:由于是logistic回归,建议显式指定family = binomial,避免glm默认使用高斯线性模型族。

内容的提问来源于stack exchange,提问作者Joshua Entrop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 23:16:16