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

如何在R的for循环中为GAM动态指定输入预测变量?

批量运行广义可加模型(GAM)并提取结果至数据框的问题解决

需求:在R中为数据框内每个预测变量与Effect列分别拟合GAM模型,提取每个模型的R平方值、p值及对应预测变量名称,最终整合到一个数据框中。

示例输入数据

input_data <- data.frame(
  Effect = c(1, 4, 6),
  `Predictor 1` = c(1, 2, 14),
  `Predictor 2` = c(4, 7, 7),
  `Predictor 3` = c(4, 1, 6)
)

尝试的代码

for (i in 2:4){
  gam_predictor <- colnames(input_data[,i])
  gam_output <- gam(Effect~s(gam_predictor, k = 4), data = input_data, method="REML")
}

报错信息

Error in model.frame.default(formula = Effect ~ 1 + gam_predictor, data = input_data, :
variable lengths differ (found for 'gam_predictor')


问题原因

你遇到的核心问题是公式无法识别字符串形式的变量名。gam()函数会把公式里的gam_predictor当成一个长度为1的字符串变量,而非数据框中对应的列,因此出现变量长度不匹配的错误。

解决方法

需要动态构建合法的模型公式,将字符串形式的预测变量名转换为公式可识别的变量引用。以下是两种实用方案:

方案1:拼接字符串构建公式

通过paste0()拼接公式字符串,再用as.formula()转换为公式对象:

library(mgcv)

# 初始化结果存储数据框
gam_results <- data.frame(
  Predictor = character(),
  R_squared = numeric(),
  P_value = numeric(),
  stringsAsFactors = FALSE
)

# 遍历所有预测变量列
for (i in 2:ncol(input_data)) {
  pred_name <- colnames(input_data)[i]
  # 动态生成公式
  gam_formula <- as.formula(paste0("Effect ~ s(", pred_name, ", k = 4)"))
  # 拟合GAM模型
  gam_output <- gam(gam_formula, data = input_data, method = "REML")
  
  # 提取结果:R平方和光滑项p值
  r_sq <- summary(gam_output)$r.sq
  p_val <- summary(gam_output)$s.table[1, "p-value"]
  
  # 追加结果到数据框
  gam_results <- rbind(gam_results, data.frame(
    Predictor = pred_name,
    R_squared = r_sq,
    P_value = p_val
  ))
}

# 查看最终结果
print(gam_results)

方案2:用reformulate()构建公式(更简洁)

reformulate()可以直接将变量名字符串转换为公式,无需手动拼接:

library(mgcv)

gam_results <- data.frame(
  Predictor = character(),
  R_squared = numeric(),
  P_value = numeric(),
  stringsAsFactors = FALSE
)

for (i in 2:ncol(input_data)) {
  pred_name <- colnames(input_data)[i]
  # 直接生成公式:响应变量为Effect,预测项为光滑函数
  gam_formula <- reformulate(paste0("s(", pred_name, ", k=4)"), response = "Effect")
  gam_output <- gam(gam_formula, data = input_data, method = "REML")
  
  r_sq <- summary(gam_output)$r.sq
  p_val <- summary(gam_output)$s.table[1, "p-value"]
  
  gam_results <- rbind(gam_results, data.frame(
    Predictor = pred_name,
    R_squared = r_sq,
    P_value = p_val
  ))
}

print(gam_results)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 19:10:19