循环中计算含二次项回归的调整R²:lm公式非线性项引用咨询
解决方法:给每个x变量添加二次项并计算调整R²
嗨,这个问题我帮你梳理清楚~首先得说:你直接用lm(y ~ . + I(.^2), data = tempMod)的写法行不通,原因是这里的.代表tempMod里除y之外的所有变量,而I(.^2)会把整个数据框(除y外)当作一个整体去平方,这不是你想要的“每个x变量单独加二次项”的效果,甚至会引发错误。
下面给你两种可行的解决方案,先提个小细节:你的variable向量里包含了x4,但你的data数据框里并没有这个变量,记得要么去掉x4,要么补充对应的数据哦。
方法1:修改原有的循环代码
我们可以针对每个x变量,手动构造包含线性项和二次项的公式,替换掉原来的. 写法:
library(dplyr) # 先修正variable,去掉不存在的x4 variable <- c("x1", "x2", "x3") # 创建空数据框存储结果 results <- data.frame(dataID = integer(), variable = character(), adj_r2 = numeric()) for(v in seq_along(variable)){ varref <- variable[v] # 选择需要的列:y、dataID和当前x变量 temp <- data %>% dplyr::select(y, dataID, all_of(varref)) modID <- sort(unique(temp$dataID)) for(m in seq_along(modID)){ modRef <- modID[m] tempMod <- temp %>% dplyr::filter(dataID == modRef) %>% dplyr::select(-dataID) # 构造公式:y ~ x + I(x^2) formula <- as.formula(paste0("y ~ ", varref, " + I(", varref, "^2)")) # 拟合模型并提取调整R² Rsq <- summary(lm(formula, data = tempMod))$adj.r.squared # 存入结果 results <- rbind(results, data.frame(dataID = modRef, variable = varref, adj_r2 = Rsq)) } }
方法2:用tidyverse简化代码(推荐)
循环写法比较繁琐,用dplyr+tidyr+purrr的组合可以更高效地实现需求,代码可读性也更强:
library(dplyr) library(tidyr) library(purrr) variable <- c("x1", "x2", "x3") # 把宽格式数据转为长格式,每个x变量单独成一行 long_data <- data %>% pivot_longer(cols = all_of(variable), names_to = "variable", values_to = "x_value") # 按dataID和variable分组,拟合模型并提取调整R² results <- long_data %>% group_by(dataID, variable) %>% summarise( adj_r2 = summary(lm(y ~ x_value + I(x_value^2), data = cur_data()))$adj.r.squared, .groups = "drop" )
这个方法的逻辑是:先把所有x变量整合到一列里,再按dataID和variable分组,每组对应一个需要拟合的模型,最后直接计算并提取调整R²即可。
内容的提问来源于stack exchange,提问作者89_Simple
相关产品推荐
相关产品推荐

