R语言循环生成多组正态分布并执行Bartlett检验与ANOVA的代码问题
问题分析与代码修正
原代码核心错误点
- 每组仅存1个观测值:
Group1[i] <- rnorm(n=10,...)试图把10个值赋值给向量的单个元素,R会自动只保留第一个值,导致每组实际只有1个数据。 - 数据格式错误:拟合
lm(num~group)时用了宽格式的data2,但该数据框没有num和group列,应该用转换后的长格式data.long2。 - 结果存储错误:
bartlett.test()返回的是列表对象,lm()返回模型对象,无法直接存入普通向量,需要提取具体的统计量(比如p值)。 - 全局变量累积冗余:循环中不断往
Group1/2/3里加数据,会导致数据框越来越大,完全没必要——每次循环只需要处理当前模拟的一组数据。
修正后的代码
library(tidyverse) library(car) v <- 100000 # 预分配结果向量,提升效率 bartlett_p <- numeric(v) anova_p <- numeric(v) for (i in 1:v) { # 每次循环生成三组各10个数据,直接构造成长格式 data_long <- tibble( group = rep(c("Group1", "Group2", "Group3"), each = 10), num = c( rnorm(n = 10, mean = 5, sd = 5), rnorm(n = 10, mean = 5, sd = 10), rnorm(n = 10, mean = 5, sd = 15) ) ) # 提取Bartlett检验的p值 bartlett_result <- bartlett.test(num ~ group, data = data_long) bartlett_p[i] <- bartlett_result$p.value # 拟合模型并提取ANOVA的p值(Type III) fit <- lm(num ~ group, data = data_long) anova_result <- Anova(fit, type = 3) anova_p[i] <- anova_result[1, 4] } # 查看结果示例 head(bartlett_p) head(anova_p)
关键修正说明
- 预分配向量:用
numeric(v)提前创建指定长度的结果向量,比循环中不断扩展向量快得多,适合10万次的大规模循环。 - 直接生成长格式数据:每次循环直接构造符合分析要求的长格式数据框,避免宽转长的额外步骤,同时避免全局变量冗余。
- 正确提取统计量:从
bartlett.test()和Anova()的结果中提取具体的p值存入向量,而不是试图保存整个对象。 - 使用正确的数据格式拟合模型:用长格式的
data_long作为lm()的输入,匹配公式num~group的要求。
内容的提问来源于stack exchange,提问作者Fishy Science
相关产品推荐
相关产品推荐

