R语言For循环内filter()失效 分组拟合VBGF结果全部相同求助
问题原因
你可以先在循环内tmp1 <- filter(df,Serial_No==Serial_Nos[i])这行后加print(nrow(tmp1))验证:如果每次输出都是总数据行数28,说明filter确实失效,核心原因是全局环境存在和数据列同名的Serial_No向量,filter匹配时发生了作用域冲突。
修复方案
快速修复原循环代码
直接修改filter语句,用.data代词明确指定引用数据框内的列,避免和全局变量冲突:
# 原代码 tmp1 <- filter(df,Serial_No==Serial_Nos[i]) # 修改为 tmp1 <- filter(df, .data$Serial_No == Serial_Nos[i])
同时建议优化存在作用域风险的predict2函数,避免后续隐藏问题:
# 原函数 依赖全局ages变量 predict2 <- function(x) predict(x,data.frame(age=ages)) # 修改为带参数的形式 predict2 <- function(x, ages) predict(x, data.frame(age=ages)) # 对应修改Boot调用行 boot2 <- Boot(fit1,f=predict2, ages=ages)
更稳妥的无循环写法
你也可以改用dplyr嵌套分组拟合的写法,完全避开循环变量冲突问题,代码更简洁不易出错:
library(dplyr) library(FSA) library(car) library(tidyr) vb <- vbFuns() ages <- seq(-1, 16, 0.2) # 按Serial_No分组拟合+批量输出结果 fit_result <- df %>% nest_by(Serial_No, .keep = TRUE) %>% mutate( # 拟合VBGF模型 fit = list(nls(tl ~ vb(age, Linf, K, t0), data = data, start = vbStarts(tl~age, data = data))), # 提取模型系数 Linf = coef(fit)[["Linf"]], K = coef(fit)[["K"]], t0 = coef(fit)[["t0"]], # 生成全age范围的预测值和置信区间 pred_df = list(data.frame( age = ages, pred_tl = predict(fit, newdata = data.frame(age = ages)), confint(Boot(fit, f = \(mod) predict(mod, newdata = data.frame(age = ages)))) )) ) %>% unnest(pred_df)
运行后fit_result里就包含了所有分组的系数、每个age对应的预测值和置信区间,不需要手动循环绑定结果。
内容的提问来源于stack exchange,提问作者Becky
相关产品推荐
相关产品推荐

