1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Two-way mixed repeated-measures ANOVA

1
Posted at

afex::aov_ez() で mixed repeated-measures ANOVA を行い、その後に pairwise比較と各比較の効果量を出す基本例の記録。

# 初回のみ
# install.packages(c("readr", "dplyr", "afex", "emmeans"))

library(readr)
library(dplyr)
library(afex)
library(emmeans)
# データ読み込み
dat <- read_csv("data.csv")

# 列の型を指定
dat <- dat %>%
  mutate(
    subject   = factor(subject),
    Dose      = factor(Dose),
    Timepoint = factor(Timepoint, levels = c("T1", "T2", "T3"))
  )
# Mixed repeated measures ANOVA
# Dose: 群間要因
# Timepoint: 反復測定要因
fit_aov <- aov_ez(
  id = "subject",
  dv = "Value",
  between = "Dose",
  within = "Timepoint",
  data = dat,
  type = 3
)

# ANOVA表
fit_aov

(1). interactionが有意な場合
A. 各timepointで treatment群間比較
「どの時点でcontrolとdrugが違うか」を見る場合です。

emm_treat_by_time <- emmeans(fit, ~ treatment | timepoint)

pair_treat_by_time <- pairs(
  emm_treat_by_time,
  adjust = "bonferroni"
)

pair_treat_by_time

B. 各treatment群内で timepoint間比較
「各群でどのtimepoint間が違うか」を見る場合です。

emm_time_by_treat <- emmeans(fit, ~ timepoint | treatment)

pair_time_by_treat <- pairs(
  emm_time_by_treat,
  adjust = "bonferroni"
)

pair_time_by_treat

効果量の計算

library(dplyr)
library(emmeans)

effect_size_result <- bind_rows(
  lapply(levels(dat$Time), function(tt) {

    dat_t <- dat %>% filter(Time == tt)

    # このモデルは、各時点の効果量の算出に使用
    fit_t <- lm(Intensity ~ Treatment, data = dat_t)
    emm_t <- emmeans(fit_t, ~ Treatment)

    es_t <- eff_size(
      emm_t,
      sigma = sigma(fit_t),
      edf = df.residual(fit_t),
      method = "pairwise"
    )

    as.data.frame(es_t) %>%
      mutate(Time = tt, .before = 1)
  })
)

effect_size_result
# 初回のみ
# install.packages("effectsize")

library(dplyr)
library(tidyr)

wide <- dat %>%
  select(Subject, Treatment, Time, Intensity) %>%
  pivot_wider(
    id_cols = c(Subject, Treatment),
    names_from = Time,
    values_from = Intensity,
    names_prefix = "Time_"
  )

time_pairs <- combn(
  levels(dat$Time),
  2,
  simplify = FALSE
)

effect_size_time <- bind_rows(
  lapply(levels(dat$Treatment), function(tr) {

    group_data <- wide %>% filter(Treatment == tr)

    bind_rows(lapply(time_pairs, function(tp) {

      x <- group_data[[paste0("Time_", tp[1])]]
      y <- group_data[[paste0("Time_", tp[2])]]

      # 同じ個体の両時点の値がそろっているペアを使用
      keep <- complete.cases(x, y)
      x <- x[keep]
      y <- y[keep]

      es <- effectsize::cohens_d(
        x,
        y,
        paired = TRUE,
        ci = 0.95,
        alternative = "two.sided"
      )

      tibble(
        Treatment = tr,
        contrast = paste(tp[1], "-", tp[2]),
        n = length(x),
        mean_difference = mean(x - y),
        dz = es$Cohens_d,
        CI_low = es$CI_low,
        CI_high = es$CI_high
      )
    }))
  })
)

effect_size_time

p値は反復測定ANOVAモデルに基づく比較、効果量は実測値の対応差に基づく(d_z)という組み合わせです。論文では単に「Cohen’s d」ではなく、“Cohen’s (d_z), calculated using the standard deviation of paired differences”**と定義を明示する

(2). interactionなし、timepoint主効果のみ有意な場合
この場合は、群をまとめてtimepoint間比較します。

emm_time <- emmeans(fit, ~ timepoint)

pair_time <- pairs(
  emm_time,
  adjust = "bonferroni"
)

pair_time

効果量

# emm_time <- emmeans(fit_aov, ~ Time)
# pairs(emm_time, adjust = "holm")

library(dplyr)
library(tidyr)
library(emmeans)

# datにはSubject, Treatment, Time, Intensityがある想定
wide <- dat %>%
  select(Subject, Treatment, Time, Intensity) %>%
  pivot_wider(
    id_cols = c(Subject, Treatment),
    names_from = Time,
    values_from = Intensity,
    names_prefix = "Time_"
  )

time_pairs <- combn(
  levels(dat$Time),
  2,
  simplify = FALSE
)

effect_size_time <- bind_rows(
  lapply(time_pairs, function(tp) {

    pair_dat <- wide %>%
      mutate(
        difference =
          .data[[paste0("Time_", tp[1])]] -
          .data[[paste0("Time_", tp[2])]]
      ) %>%
      filter(!is.na(difference))

    # 各個体の時点間差をTreatmentで調整
    fit_diff <- lm(difference ~ Treatment, data = pair_dat)

    # Treatmentを等しい重みで平均した時点間差
    emm_diff <- emmeans(fit_diff, ~ 1, weights = "equal")

    # 推定された差を、その残差SDで標準化
    es <- eff_size(
      emm_diff,
      sigma = sigma(fit_diff),
      edf = df.residual(fit_diff),
      method = "identity"
    )

    es_table <- as.data.frame(
      summary(es, infer = c(TRUE, FALSE), level = 0.95)
    )

    tibble(
      contrast = paste(tp[1], "-", tp[2]),
      n = nrow(pair_dat),
      dz_adjusted = es_table$effect.size,
      CI_low = es_table$lower.CL,
      CI_high = es_table$upper.CL
    )
  })
)

effect_size_time

効果量は、各時点ペアの個体内差を、Treatmentで調整した差のSDで標準化した(d_z)型の指標として、以下で95%信頼区間とともに算出。各個体の差にlm(difference ~ Treatment)を当て、Treatmentを等しい重みで平均するため、上記のemmeans()と比較の対象がそろいます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?