R中如何单轴随机置换估计回归斜率并修复代码报错
报错原因
你遇到的Error in filter(., sp == "A") : object '*tmp*' not found报错根源是dplyr管道%>%语法使用错误:你在管道串联的流程中直接插入mod1 <- lm(...)这类赋值语句,管道会默认将前一步输出的数据集作为第一个参数传给赋值函数,导致逻辑断裂,无法识别临时对象。
原代码还存在几处可优化/逻辑偏差问题:
- 4个物种的处理逻辑完全一致,重复编写4段代码冗余度高,后续修改维护麻烦
- 单次线性模型拟合得到的截距、斜率都是单个标量,外层套
mean()函数没有实际作用 - 组内打乱构建零分布属于置换检验,应该使用无放回抽样,原代码设置
replace=TRUE是有放回抽样,不符合零分布构建逻辑,需要做bootstrap时再改回该参数即可。
修正后可运行代码
set.seed(111) library(truncnorm) library(dplyr) library(tibble) # 构建示例数据集 x.real <- rtruncnorm(n = 288, a = 0, b = 10, mean = 5, sd = 2) y.real <- rnorm(288, 0, 4) sp <- rep(c("A","B","C","D"), each = 72) df <- data.frame(x.real, y.real, sp) # 初始化结果存储表 output <- tibble( y.intercept = numeric(), slope = numeric(), sp = character(), set = numeric() ) set.seed(42) n_iter <- 1000 sp_groups <- unique(df$sp) for(i in 1:n_iter){ # 遍历所有物种分组,避免重复代码 iter_result <- lapply(sp_groups, function(current_sp){ sub_data <- filter(df, sp == current_sp) # 组内无放回打乱x.real拟合模型 fit <- lm(y.real ~ sample(x.real, length(x.real), replace = FALSE), data = sub_data) data.frame( y.intercept = coef(fit)[1], slope = coef(fit)[2], sp = current_sp, set = i ) }) # 追加当前迭代结果到总表 output <- bind_rows(output, bind_rows(iter_result)) } # 计算1000次迭代各物种的斜率零期望均值(按需运行) slope_null_mean <- output %>% group_by(sp) %>% summarise(mean_null_slope = mean(slope), .groups = "drop")
结果说明
运行后生成的output完全匹配要求的格式,共4000行(1000次迭代*4个物种),每列含义:
y.intercept:对应迭代、对应物种的线性模型截距估计值slope:对应迭代、对应物种的线性模型斜率估计值sp:物种分组标识set:迭代编号,取值范围1-1000
内容的提问来源于stack exchange,提问作者Rspacer
相关产品推荐
相关产品推荐

