就这个实验设计(前测/后测实验组-对照组设计),这些方法(Two way repeated ANOVA/between and within subject mixed ANOVA/DID)给出的结果应该都是一样的
library(tidyverse)
library(mvtnorm)
library(ez)
library(lme4)
set.seed(0)
N = 100 # 样本量
cor_mat = matrix(c(1.0, 0.6, 0.6, 1.0), 2, 2) # 前后测数据有中等强度的相关
xy <- mvtnorm::rmvnorm(N, c(0.0, 0.0), cor_mat)
df <- tibble::tibble(
sid = seq(N), # 学生id
x = xy[, 1], # 前测分数
t = sample(0:1, N, TRUE), # 实验分组
# t = sample(rep(0:1, each = N / 2), replace = FALSE), # 实验分组
y = xy[, 2] # 后测分数
)
df_long = df |>
pivot_longer(
cols = c('y', 'x'),
names_to = 'is_after',
values_to = 'y'
) |>
mutate(is_after = if_else(is_after == 'y', 1, 0))
df_long$t = as.factor(df_long$t)
df_long$is_after = as.factor(df_long$is_after)
df_long$sid = as.factor(df_long$sid)
心理学/教育学方向一般以前用重复测量方差分析,大概就是你说的Two way repeated ANNOVA. 这个结果和spss中「重复测量方差分析」的结果应该是一样的。
repeat_aov = ezANOVA(data = df_long, dv = y, wid = sid, between = t, within = is_after, type = 3)
print(repeat_aov$ANOVA[3, ], digits = 6)
Effect DFn DFd F p p<.05 ges
t:is_after 1 98 0.007581415 0.9307925 1.706315e-05
下面就是between and within subject mixed ANOVA?这个结果和上面的其实是一样的,F就是t value的平方
lme_mod = summary(lmer(y ~ t * is_after + (1|sid), data = df_long))
print(lme_mod$coefficients['t1:is_after1', ], digits = 6)
Estimate Std. Error t value
0.0149626 0.1718430 0.0870713
或者做个面板回归
panel = plm::pdata.frame(df_long, "sid")
plm_mod = summary(plm::plm(y ~ t * is_after, data = panel, model = "within"))
print(plm_mod$coefficients['t1:is_after1', ], digits = 6)
Estimate Std. Error t-value Pr(>|t|)
0.0149626 0.1718430 0.0870713 0.9307925
有的人喜欢把这种实验设计叫DID,就是前后测的差对t回归,这个结果也是一样的
did_mod = summary(lm(y - x ~ t, data = df))
print(did_mod$coefficients['t', ], digits = 6)
Estimate Std. Error t value Pr(>|t|)
0.0149626 0.1718430 0.0870713 0.9307925
我个人一般就直接做回归,前测分组做控制变量,就是ANCOVA。这个结果和上面有一点小的差异,感兴趣可以看看这个https://stats.stackexchange.com/questions/3466/best-practice-when-analysing-pre-post-treatment-control-designs
ancova_mod = summary(lm(y ~ t + x, data = df))
print(ancova_mod$coefficients['t', ], digits = 6)
Estimate Std. Error t value Pr(>|t|)
-0.101056 0.146882 -0.688010 0.493088