SEED <- 123; set.seed(SEED)
suppressPackageStartupMessages({
library(readxl)
library(dplyr)
library(stringr)
library(tidyr)
library(forcats)
library(lme4); library(lmerTest)
library(emmeans)
library(purrr)
library(tibble)
})
path_scales <- "C:/Users/97380/Documents/LFF_data process/Scale/scale_data_pre.xlsx"
sheet_name <- 1 # 或者 "变量最终得分"
raw <- read_excel(path_scales, sheet = sheet_name)
dat_wide <- raw %>%
mutate(
group = as.character(Group),
group = recode(group, `1`="control", `2`="training", .default = group),
group = factor(group, levels = c("control","training"))
)
# 2) 标准化 ID 与 group(1->control, 2->training)
dat_wide <- raw %>%
rename(ID = ID, Group = Group) %>%
mutate(
group = as.character(Group),
group = recode(group, `1` = "control", `2` = "training", .default = group),
group = factor(group, levels = c("control","training"))
)
# 3) 选择所有量表列:以 pre_/post_/fu_ 开头的列
scale_cols <- names(dat_wide)[str_detect(names(dat_wide), "^(pre|post|fu)_")]
# 4) 长数据:time 从列名提取,metric 为量表名,score 为数值
scales_long <- dat_wide %>%
select(ID, group, all_of(scale_cols)) %>%
pivot_longer(all_of(scale_cols), names_to = "name", values_to = "score") %>%
extract(name, into = c("time","metric"), regex = "^(pre|post|fu)_(.+)$") %>%
mutate(
time = factor(time, levels = c("pre","post","fu")),
metric = metric %>% str_replace_all("\u3000", " ") %>% str_squish(), # 清理全角空格
score = suppressWarnings(as.numeric(score))
) %>%
select(ID, group, time, metric, score) %>%
arrange(metric, ID, time)
# 选 VVIQ,准备数据
metric_name <- "VVIQ"
dat_vviq <- scales_long %>%
filter(metric == metric_name) %>%
mutate(
group = fct_relevel(group, "control", "training"),
time = fct_relevel(time, "pre", "post", "fu")
)
# 小工具:按时间窗口建模
mk_fit <- function(df, times, label){
d <- df %>% filter(time %in% times) %>% droplevels() %>%
mutate(time = fct_relevel(time, times))
fit <- lmer(score ~ group * time + (1|ID), data = d, REML = TRUE)
list(fit = fit, label = label)
}
fits <- list(
mk_fit(dat_vviq, c("pre","post"), "pre-post"),
mk_fit(dat_vviq, c("pre","fu"), "pre-fu"),
mk_fit(dat_vviq, c("post","fu"), "post-fu")
)
# ===== 固定效应:t / SE / p / d =====
fixed_tbl <- map_dfr(fits, function(x){
fit <- x$fit; lab <- x$label; sig <- sigma(fit)
co <- as.data.frame(coef(summary(fit)))
tibble(
model = lab,
term = rownames(co),
estimate = co[,"Estimate"],
std.error = co[,"Std. Error"],
df = co[,"df"],
t = co[,"t value"],
p = co[,"Pr(>|t|)"],
d = estimate / sig,
SE_d = std.error / sig,
d_low = d + qt(0.025, df) * SE_d,
d_high = d + qt(0.975, df) * SE_d
)
})
# 组内简单效应:post−pre / fu−pre
within_tbl <- map_dfr(fits[1:2], function(x){
fit <- x$fit; lab <- x$label; sig <- sigma(fit)
emm <- emmeans(fit, ~ time | group)
con <- if (lab == "pre–post") list(post_minus_pre = c(-1, 1))
else list(fu_minus_pre = c(-1, 1))
w <- summary(contrast(emm, con, by = "group", adjust = "none"))
as.data.frame(w) %>%
mutate(
model = lab,
d = estimate / sig,
SE_d = SE / sig,
d_low = d + qt(0.025, df) * SE_d,
d_high = d + qt(0.975, df) * SE_d
) %>%
select(model, group, contrast, estimate, SE, df, t.ratio, p.value, d, SE_d, d_low, d_high)
})
# 查看结果
fixed_tbl
## # A tibble: 12 × 11
## model term estimate std.error df t p d SE_d d_low
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 pre-post (Inter… 79.5 3.34 81.5 23.8 1.89e-38 7.35 0.309 6.74
## 2 pre-post groupt… -1.13 4.72 81.5 -0.240 8.11e- 1 -0.105 0.437 -0.974
## 3 pre-post timepo… 6.80 2.79 58.0 2.44 1.79e- 2 0.629 0.258 0.112
## 4 pre-post groupt… -17.0 3.95 58.0 -4.32 6.29e- 5 -1.58 0.365 -2.31
## 5 pre-fu (Inter… 79.5 3.37 80.4 23.6 7.65e-38 7.43 0.316 6.81
## 6 pre-fu groupt… -1.13 4.77 80.4 -0.238 8.13e- 1 -0.106 0.446 -0.994
## 7 pre-fu timefu 3.00 2.76 58.0 1.09 2.82e- 1 0.280 0.258 -0.237
## 8 pre-fu groupt… -9.74 3.90 58.0 -2.50 1.54e- 2 -0.911 0.365 -1.64
## 9 post-fu (Inter… 86.3 3.31 72.3 26.1 1.76e-38 10.1 0.387 9.33
## 10 post-fu groupt… -18.2 4.68 72.3 -3.88 2.28e- 4 -2.13 0.548 -3.22
## 11 post-fu timefu -3.80 2.21 58.0 -1.73 8.99e- 2 -0.445 0.258 -0.962
## 12 post-fu groupt… 7.29 3.12 58.0 2.34 2.28e- 2 0.854 0.365 0.123
## # ℹ 1 more variable: d_high <dbl>
within_tbl
## model group contrast estimate SE df t.ratio p.value
## 1 pre-post control fu_minus_pre 6.800000 2.791218 58 2.436212 0.0179338490
## 2 pre-post training fu_minus_pre -10.233333 2.791218 58 -3.666260 0.0005356436
## 3 pre-fu control fu_minus_pre 2.995000 2.759805 58 1.085222 0.2823136701
## 4 pre-fu training fu_minus_pre -6.744333 2.759805 58 -2.443772 0.0175975727
## d SE_d d_low d_high
## 1 0.6290273 0.2581989 0.1121860 1.1458685
## 2 -0.9466243 0.2581989 -1.4634656 -0.4297831
## 3 0.2802030 0.2581989 -0.2366382 0.7970443
## 4 -0.6309792 0.2581989 -1.1478204 -0.1141379
fixed_d_from_fit <- function(fit){
sig <- sigma(fit)
co <- as.data.frame(coef(summary(fit)))
tibble(
term = rownames(co),
estimate = co[,"Estimate"],
std.error = co[,"Std. Error"],
df = co[,"df"],
t = co[,"t value"],
p = co[,"Pr(>|t|)"],
d = estimate / sig,
SE_d = std.error / sig,
d_low = d + qt(0.025, df) * SE_d,
d_high = d + qt(0.975, df) * SE_d
)
}
within_d_from_fit <- function(fit, window){
emm <- emmeans(fit, ~ time | group)
sig <- sigma(fit)
if (identical(window, c("pre","post"))) {
w <- summary(contrast(emm, list(post_minus_pre = c(-1, 1)),
by = "group", adjust = "none"))
} else if (identical(window, c("pre","fu"))) {
w <- summary(contrast(emm, list(fu_minus_pre = c(-1, 1)),
by = "group", adjust = "none"))
} else return(NULL)
as.data.frame(w) %>%
mutate(
d = estimate / sig,
SE_d = SE / sig,
d_low = d + qt(0.025, df) * SE_d,
d_high = d + qt(0.975, df) * SE_d
) %>%
select(group, contrast, estimate, SE, df, t.ratio, p.value, d, SE_d, d_low, d_high)
}
mk_fit <- function(df, times, label){
d <- df %>% filter(time %in% times) %>% droplevels() %>%
mutate(time = fct_relevel(time, times),
group = fct_relevel(group, "control","training"))
fit <- lmer(score ~ group * time + (1|ID), data = d, REML = TRUE)
list(fit = fit, label = label, window = times)
}
###TEPS — anticipatory
metric_name <- "TEPS_anticipatory"
dat_teps_a <- scales_long |>
mutate(metric = as.character(metric)) |>
filter(metric == metric_name) |>
mutate(group = fct_relevel(group, "control","training"),
time = fct_relevel(time, "pre","post","fu"))
fits_teps_a <- list(
mk_fit(dat_teps_a, c("pre","post"), "pre–post"),
mk_fit(dat_teps_a, c("pre","fu"), "pre–fu"),
mk_fit(dat_teps_a, c("post","fu"), "post–fu")
)
TEPS_anti_fixed <- map_dfr(fits_teps_a, \(x)
fixed_d_from_fit(x$fit) |> mutate(model = x$label, .before = 1))
TEPS_anti_within <- map_dfr(fits_teps_a[1:2], \(x)
within_d_from_fit(x$fit, x$window) |> mutate(model = x$label, .before = 1))
TEPS_anti_fixed
## # A tibble: 12 × 11
## model term estimate std.error df t p d SE_d d_low
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 pre–post (Int… 35.6 1.22 75.3 29.2 9.25e-43 10.4 0.355 9.64
## 2 pre–post grou… -0.133 1.73 75.3 -0.0772 9.39e- 1 -0.0388 0.502 -1.04
## 3 pre–post time… -1.47 0.888 58.0 -1.65 1.04e- 1 -0.426 0.258 -0.943
## 4 pre–post grou… 4.27 1.26 58.0 3.40 1.24e- 3 1.24 0.365 0.510
## 5 pre–fu (Int… 35.6 1.19 78.3 29.8 1.64e-44 9.83 0.330 9.18
## 6 pre–fu grou… -0.133 1.69 78.3 -0.0790 9.37e- 1 -0.0368 0.466 -0.965
## 7 pre–fu time… -1.77 0.935 58.0 -1.89 6.37e- 2 -0.488 0.258 -1.00
## 8 pre–fu grou… 4.68 1.32 58.0 3.54 7.96e- 4 1.29 0.365 0.562
## 9 post–fu (Int… 34.1 1.17 74.1 29.3 1.84e-42 10.7 0.366 9.99
## 10 post–fu grou… 4.13 1.65 74.1 2.51 1.44e- 2 1.30 0.518 0.266
## 11 post–fu time… -0.300 0.822 58.0 -0.365 7.16e- 1 -0.0943 0.258 -0.611
## 12 post–fu grou… 0.413 1.16 58.0 0.355 7.24e- 1 0.130 0.365 -0.601
## # ℹ 1 more variable: d_high <dbl>
TEPS_anti_within
## model group contrast estimate SE df t.ratio p.value
## 1 pre–post control post_minus_pre -1.466667 0.8880647 58 -1.651531 0.104034848
## 2 pre–post training post_minus_pre 2.800000 0.8880647 58 3.152923 0.002559407
## 3 pre–fu control fu_minus_pre -1.766667 0.9346467 58 -1.890197 0.063731647
## 4 pre–fu training fu_minus_pre 2.912667 0.9346467 58 3.116329 0.002846887
## d SE_d d_low d_high
## 1 -0.4264235 0.2581989 -0.9432648 0.09041770
## 2 0.8140813 0.2581989 0.2972401 1.33092253
## 3 -0.4880468 0.2581989 -1.0048881 0.02879439
## 4 0.8046327 0.2581989 0.2877915 1.32147392
### TEPS — consummatory
metric_name <- "TEPS_consummatory"
dat_teps_c <- scales_long |>
mutate(metric = as.character(metric)) |>
filter(metric == metric_name) |>
mutate(group = fct_relevel(group, "control","training"),
time = fct_relevel(time, "pre","post","fu"))
fits_teps_c <- list(
mk_fit(dat_teps_c, c("pre","post"), "pre–post"),
mk_fit(dat_teps_c, c("pre","fu"), "pre–fu"),
mk_fit(dat_teps_c, c("post","fu"), "post–fu")
)
TEPS_cons_fixed <- map_dfr(fits_teps_c, \(x)
fixed_d_from_fit(x$fit) |> mutate(model = x$label, .before = 1))
TEPS_cons_within <- map_dfr(fits_teps_c[1:2], \(x)
within_d_from_fit(x$fit, x$window) |> mutate(model = x$label, .before = 1))
TEPS_cons_fixed
## # A tibble: 12 × 11
## model term estimate std.error df t p d SE_d d_low
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 pre–post (Inte… 45.1 1.31 78.2 34.5 4.87e-49 11.4 0.331 10.7
## 2 pre–post group… -3.43 1.85 78.2 -1.85 6.75e- 2 -0.868 0.468 -1.80
## 3 pre–post timep… -1.90 1.02 58.0 -1.86 6.80e- 2 -0.480 0.258 -0.997
## 4 pre–post group… 5.47 1.44 58.0 3.78 3.68e- 4 1.38 0.365 0.651
## 5 pre–fu (Inte… 45.1 1.32 78.7 34.1 6.55e-49 11.1 0.327 10.5
## 6 pre–fu group… -3.43 1.87 78.7 -1.83 7.05e- 2 -0.847 0.462 -1.77
## 7 pre–fu timefu -1.70 1.05 58.0 -1.62 1.10e- 1 -0.420 0.258 -0.936
## 8 pre–fu group… 5.10 1.48 58.0 3.45 1.05e- 3 1.26 0.365 0.529
## 9 post–fu (Inte… 43.2 1.25 69.5 34.7 1.39e-45 14.9 0.428 14.0
## 10 post–fu group… 2.03 1.76 69.5 1.15 2.53e- 1 0.698 0.606 -0.510
## 11 post–fu timefu 0.200 0.752 58.0 0.266 7.91e- 1 0.0687 0.258 -0.448
## 12 post–fu group… -0.363 1.06 58.0 -0.342 7.34e- 1 -0.125 0.365 -0.856
## # ℹ 1 more variable: d_high <dbl>
TEPS_cons_within
## model group contrast estimate SE df t.ratio p.value
## 1 pre–post control post_minus_pre -1.900000 1.021624 58 -1.859783 0.0679900292
## 2 pre–post training post_minus_pre 3.566667 1.021624 58 3.491172 0.0009262945
## 3 pre–fu control fu_minus_pre -1.700000 1.046183 58 -1.624954 0.1095947847
## 4 pre–fu training fu_minus_pre 3.403333 1.046183 58 3.253094 0.0019056010
## d SE_d d_low d_high
## 1 -0.4801940 0.2581989 -0.9970352 0.03664726
## 2 0.9014168 0.2581989 0.3845755 1.41825799
## 3 -0.4195613 0.2581989 -0.9364026 0.09727991
## 4 0.8399453 0.2581989 0.3231041 1.35678655
metric_name <- "BDI"
dat_bdi <- scales_long %>%
filter(metric == metric_name) %>%
mutate(group = fct_relevel(group, "control","training"),
time = fct_relevel(time, "pre","post","fu"))
# 三模型
fits_bdi <- list(
mk_fit(dat_bdi, c("pre","post"), "pre-post"),
mk_fit(dat_bdi, c("pre","fu"), "pre-fu"),
mk_fit(dat_bdi, c("post","fu"), "post-fu")
)
# 固定效应 t/SE/p/d
BDI_fixed <- map_dfr(fits_bdi, function(x){
fixed_d_from_fit(x$fit) %>%
mutate(model = x$label, .before = 1)
})
# 组内简单效应( pre-post 与 pre-fu)
BDI_within <- map_dfr(fits_bdi[1:2], function(x){
within_d_from_fit(x$fit, x$window) %>%
mutate(model = x$label, .before = 1)
})
# 查看结果
BDI_fixed
## # A tibble: 12 × 11
## model term estimate std.error df t p d SE_d d_low
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 pre-post (Inte… 24.6 1.14 102. 21.6 7.15e-40 4.97 0.230 4.51
## 2 pre-post group… 0.267 1.61 102. 0.165 8.69e- 1 0.0538 0.325 -0.591
## 3 pre-post timep… -1.73 1.28 58.0 -1.35 1.81e- 1 -0.350 0.258 -0.867
## 4 pre-post group… -5.83 1.81 58.0 -3.22 2.08e- 3 -1.18 0.365 -1.91
## 5 pre-fu (Inte… 24.6 1.12 109. 21.9 9.83e-42 4.64 0.212 4.22
## 6 pre-fu group… 0.267 1.59 109. 0.168 8.67e- 1 0.0502 0.299 -0.543
## 7 pre-fu timefu -2.43 1.37 58.0 -1.77 8.13e- 2 -0.458 0.258 -0.975
## 8 pre-fu group… -7.64 1.94 58.0 -3.94 2.22e- 4 -1.44 0.365 -2.17
## 9 post-fu (Inte… 22.9 1.42 80.8 16.1 5.52e-27 5.05 0.313 4.43
## 10 post-fu group… -5.57 2.01 80.8 -2.77 6.90e- 3 -1.23 0.443 -2.11
## 11 post-fu timefu -0.700 1.17 58.0 -0.598 5.52e- 1 -0.154 0.258 -0.671
## 12 post-fu group… -1.81 1.65 58.0 -1.09 2.80e- 1 -0.399 0.365 -1.13
## # ℹ 1 more variable: d_high <dbl>
BDI_within
## model group contrast estimate SE df t.ratio
## 1 pre-post control post_minus_pre -1.733333 1.279645 58 -1.354543
## 2 pre-post training post_minus_pre -7.566667 1.279645 58 -5.913100
## 3 pre-fu control fu_minus_pre -2.433333 1.371416 58 -1.774322
## 4 pre-fu training fu_minus_pre -10.072333 1.371416 58 -7.344479
## p.value d SE_d d_low d_high
## 1 1.808167e-01 -0.3497414 0.2581989 -0.8665827 0.16709981
## 2 1.894887e-07 -1.5267558 0.2581989 -2.0435971 -1.00991461
## 3 8.125838e-02 -0.4581280 0.2581989 -0.9749693 0.05871318
## 4 7.728579e-10 -1.8963363 0.2581989 -2.4131776 -1.37949510
metric_name <- "STAIT"
dat_stait <- scales_long %>%
dplyr::filter(metric == metric_name) %>%
dplyr::mutate(
group = forcats::fct_relevel(group, "control","training"),
time = forcats::fct_relevel(time, "pre","post","fu")
)
# 三个时间窗口模型
fits_stait <- list(
mk_fit(dat_stait, c("pre","post"), "pre-post"),
mk_fit(dat_stait, c("pre","fu"), "pre-fu"),
mk_fit(dat_stait, c("post","fu"), "post-fu")
)
# 固定效应:t / SE / p / d
STAIT_fixed <- purrr::map_dfr(fits_stait, function(x){
fixed_d_from_fit(x$fit) %>%
dplyr::mutate(model = x$label, .before = 1)
})
# 组内简单效应( pre-post 与 pre-fu)
STAIT_within <- map_dfr(fits_stait[1:2], function(x){
within_d_from_fit(x$fit, x$window) %>%
dplyr::mutate(model = x$label, .before = 1)
})
# 查看结果
STAIT_fixed
## # A tibble: 12 × 11
## model term estimate std.error df t p d SE_d d_low
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 pre-post (Int… 55.5 1.41 91.0 39.4 5.50e-59 10.4 0.265 9.90
## 2 pre-post grou… 0.167 1.99 91.0 0.0837 9.33e- 1 0.0313 0.374 -0.712
## 3 pre-post time… 0.633 1.37 58.0 0.461 6.47e- 1 0.119 0.258 -0.398
## 4 pre-post grou… -5.23 1.94 58.0 -2.69 9.25e- 3 -0.983 0.365 -1.71
## 5 pre-fu (Int… 55.5 1.35 92.3 41.0 4.24e-61 10.7 0.260 10.1
## 6 pre-fu grou… 0.167 1.91 92.3 0.0872 9.31e- 1 0.0320 0.367 -0.698
## 7 pre-fu time… 0.767 1.34 58.0 0.571 5.70e- 1 0.147 0.258 -0.369
## 8 pre-fu grou… -7.26 1.90 58.0 -3.82 3.25e- 4 -1.40 0.365 -2.13
## 9 post-fu (Int… 56.1 1.51 77.9 37.2 2.30e-51 12.4 0.333 11.7
## 10 post-fu grou… -5.07 2.13 77.9 -2.38 2.00e- 2 -1.12 0.471 -2.06
## 11 post-fu time… 0.133 1.17 58.0 0.114 9.10e- 1 0.0294 0.258 -0.487
## 12 post-fu grou… -2.03 1.65 58.0 -1.23 2.25e- 1 -0.447 0.365 -1.18
## # ℹ 1 more variable: d_high <dbl>
STAIT_within
## model group contrast estimate SE df t.ratio
## 1 pre-post control post_minus_pre 0.6333333 1.374264 58 0.4608527
## 2 pre-post training post_minus_pre -4.6000000 1.374264 58 -3.3472463
## 3 pre-fu control fu_minus_pre 0.7666667 1.342964 58 0.5708767
## 4 pre-fu training fu_minus_pre -6.4930000 1.342964 58 -4.8348294
## p.value d SE_d d_low d_high
## 1 0.6466277052 0.1189917 0.2581989 -0.3978496 0.6358329
## 2 0.0014374416 -0.8642553 0.2581989 -1.3810965 -0.3474140
## 3 0.5702885762 0.1473997 0.2581989 -0.3694415 0.6642410
## 4 0.0000101826 -1.2483476 0.2581989 -1.7651888 -0.7315064
metric_name <- "RRS"
dat_rrs <- scales_long %>%
dplyr::filter(metric == metric_name) %>%
dplyr::mutate(
group = forcats::fct_relevel(group, "control","training"),
time = forcats::fct_relevel(time, "pre","post","fu")
)
# 三模型
fits_rrs <- list(
mk_fit(dat_rrs, c("pre","post"), "pre-post"),
mk_fit(dat_rrs, c("pre","fu"), "pre-fu"),
mk_fit(dat_rrs, c("post","fu"), "post-fu")
)
# 固定效应 t/SE/p/d
RRS_fixed <- purrr::map_dfr(fits_rrs, function(x){
fixed_d_from_fit(x$fit) %>%
dplyr::mutate(model = x$label, .before = 1)
}) %>%
dplyr::select(model, term, t, std.error, p, d)
# 组内简单效应(pre-post 与 pre-fu)
RRS_within <- purrr::map_dfr(fits_rrs[1:2], function(x){
within_d_from_fit(x$fit, x$window) %>%
dplyr::mutate(model = x$label, .before = 1)
}) %>%
dplyr::select(model, group, contrast, t.ratio, SE, p.value, d)
RRS_fixed
## # A tibble: 12 × 6
## model term t std.error p d
## <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 pre-post (Intercept) 3.37e+ 1 1.69 1.62e-52 9.13e+ 0
## 2 pre-post grouptraining 4.74e- 1 2.39 6.37e- 1 1.82e- 1
## 3 pre-post timepost -4.97e- 1 1.61 6.21e- 1 -1.28e- 1
## 4 pre-post grouptraining:timepost -1.71e+ 0 2.28 9.22e- 2 -6.25e- 1
## 5 pre-fu (Intercept) 3.48e+ 1 1.63 2.78e-57 8.34e+ 0
## 6 pre-fu grouptraining 4.90e- 1 2.31 6.25e- 1 1.66e- 1
## 7 pre-fu timefu -4.54e- 1 1.76 6.52e- 1 -1.17e- 1
## 8 pre-fu grouptraining:timefu -4.12e+ 0 2.49 1.23e- 4 -1.50e+ 0
## 9 post-fu (Intercept) 3.17e+ 1 1.77 1.40e-48 9.31e+ 0
## 10 post-fu grouptraining -1.10e+ 0 2.51 2.73e- 1 -4.59e- 1
## 11 post-fu timefu 6.25e-15 1.56 1.00e+ 0 1.61e-15
## 12 post-fu grouptraining:timefu -2.89e+ 0 2.20 5.42e- 3 -1.06e+ 0
RRS_within
## model group contrast t.ratio SE p.value d
## 1 pre-post control post_minus_pre -0.4967377 1.610508 6.212516e-01 -0.1282571
## 2 pre-post training post_minus_pre -2.9183341 1.610508 5.000843e-03 -0.7535106
## 3 pre-fu control fu_minus_pre -0.4536655 1.763414 6.517626e-01 -0.1171359
## 4 pre-fu training fu_minus_pre -6.2749497 1.763414 4.778693e-08 -1.6201850
erq_targets <- c("ERQ_cognitive reappraisal", "ERQ_expressive suppression")
ERQ_fixed <- list()
ERQ_within <- list()
for (metric_name in erq_targets) {
dat_erq <- scales_long %>%
dplyr::filter(metric == metric_name) %>%
dplyr::mutate(
group = forcats::fct_relevel(group, "control","training"),
time = forcats::fct_relevel(time, "pre","post","fu")
)
fits_erq <- list(
mk_fit(dat_erq, c("pre","post"), "pre-post"),
mk_fit(dat_erq, c("pre","fu"), "pre-fu"),
mk_fit(dat_erq, c("post","fu"), "post-fu")
)
# 固定效应:t / SE / p / d
fx <- purrr::map_dfr(fits_erq, function(x){
fixed_d_from_fit(x$fit) %>%
dplyr::mutate(metric = metric_name, model = x$label, .before = 1)
})
ERQ_fixed[[metric_name]] <- fx
# 组内简单效应(只做 pre–post / pre–fu)
wx <- purrr::map_dfr(fits_erq[1:2], function(x){
within_d_from_fit(x$fit, x$window) %>%
dplyr::mutate(metric = metric_name, model = x$label, .before = 1)
})
ERQ_within[[metric_name]] <- wx
}
# 合并&只保留关心的列
ERQ_fixed <- dplyr::bind_rows(ERQ_fixed) %>%
dplyr::select(metric, model, term, t, std.error, p, d) %>%
dplyr::rename(SE = std.error, p.value = p)
ERQ_within <- dplyr::bind_rows(ERQ_within) %>%
dplyr::select(metric, model, group, contrast, t.ratio, SE, p.value, d) %>%
dplyr::rename(t = t.ratio)
# 查看结果
ERQ_fixed
## # A tibble: 24 × 7
## metric model term t SE p.value d
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 ERQ_cognitive reappraisal pre-post (Intercept) 30.3 0.995 5.37e-45 10.0
## 2 ERQ_cognitive reappraisal pre-post grouptraini… -0.592 1.41 5.55e- 1 -0.277
## 3 ERQ_cognitive reappraisal pre-post timepost -0.900 0.778 3.72e- 1 -0.232
## 4 ERQ_cognitive reappraisal pre-post grouptraini… 3.06 1.10 3.35e- 3 1.12
## 5 ERQ_cognitive reappraisal pre-fu (Intercept) 32.0 0.941 5.96e-51 8.60
## 6 ERQ_cognitive reappraisal pre-fu grouptraini… -0.626 1.33 5.33e- 1 -0.238
## 7 ERQ_cognitive reappraisal pre-fu timefu 0.221 0.905 8.26e- 1 0.0571
## 8 ERQ_cognitive reappraisal pre-fu grouptraini… 1.39 1.28 1.69e- 1 0.508
## 9 ERQ_cognitive reappraisal post-fu (Intercept) 31.6 0.932 1.83e-45 11.0
## 10 ERQ_cognitive reappraisal post-fu grouptraini… 1.92 1.32 5.83e- 2 0.946
## # ℹ 14 more rows
ERQ_within
## metric model group contrast t
## 1 ERQ_cognitive reappraisal pre-post control post_minus_pre -0.89984012
## 2 ERQ_cognitive reappraisal pre-post training post_minus_pre 3.42796237
## 3 ERQ_cognitive reappraisal pre-fu control fu_minus_pre 0.22099615
## 4 ERQ_cognitive reappraisal pre-fu training fu_minus_pre 2.19007188
## 5 ERQ_expressive suppression pre-post control post_minus_pre -1.14442421
## 6 ERQ_expressive suppression pre-post training post_minus_pre 0.66758079
## 7 ERQ_expressive suppression pre-fu control fu_minus_pre -0.04595728
## 8 ERQ_expressive suppression pre-fu training fu_minus_pre -0.83963946
## SE p.value d
## 1 0.7779160 0.371926318 -0.23233772
## 2 0.7779160 0.001124862 0.88509608
## 3 0.9049931 0.825871586 0.05706096
## 4 0.9049931 0.032553728 0.56547413
## 5 0.6990415 0.257148724 -0.29548906
## 6 0.6990415 0.507048884 0.17236862
## 7 0.7253113 0.963502174 -0.01186612
## 8 0.7253113 0.404558268 -0.21679398