평균 비교가 복잡해질수록 ANOVA 계열을 구분해서 써야 한다
t-test는 두 집단 평균 비교에는 매우 강력한 도구입니다. 하지만 실제 분석에서는 금방 더 복잡한 상황을 만나게 됩니다.
- 집단이 세 개 이상일 수 있습니다.
- 같은 사람을 여러 시점에서 반복 측정할 수 있습니다.
- 두 개 이상의 요인이 동시에 영향을 줄 수 있습니다.
- 종속변수가 하나가 아니라 여러 개일 수 있습니다.
- 집단 차이를 보되, 사전 점수나 나이 같은 공변량은 보정하고 싶을 수 있습니다.
이때 필요한 것이 ANOVA 계열 분석입니다. 문제는 이름이 비슷한 분석이 많아서, 초보자 입장에서는 무엇을 언제 써야 하는지 헷갈리기 쉽다는 점입니다.
이 글은 그 혼란을 정리하기 위한 가이드입니다. 단순히 일원 분산분석만 설명하는 데서 끝내지 않고, 아래 항목까지 한 번에 연결해서 설명합니다.
- 일원 분산분석(one-way ANOVA)
- 반복측정 분산분석(repeated measures ANOVA)
- 이원 분산분석(two-way ANOVA)
- 이원 반복측정 분산분석(two-way repeated measures ANOVA)
- Mixed ANOVA
- MANOVA(다변량 분산분석)
- ANCOVA(공분산분석)
이 글에서 먼저 잡고 갈 핵심 기준
어떤 ANOVA를 써야 하는지 가장 빠르게 판단하는 기준
| 상황 | 추천 분석 |
|---|---|
| 독립집단 3개 이상 평균 비교 | 일원 분산분석 |
| 같은 사람을 여러 시점에서 반복 측정 | 반복측정 분산분석 |
| 독립변수가 2개이고 둘 다 독립집단 요인 | 이원 분산분석 |
| 같은 사람에게 두 개 이상의 반복측정 요인이 있음 | 이원 반복측정 분산분석 |
| 독립집단 요인 1개 + 반복측정 요인 1개 | Mixed ANOVA |
| 종속변수가 2개 이상 | MANOVA |
| 집단 비교를 하되 수치형 공변량을 보정 | ANCOVA |
이 글에서 용어를 이렇게 구분한다
국문 자료에서는 이원 반복측정 분산분석과 Mixed ANOVA를 혼용해서 쓰는 경우가 적지 않습니다. 하지만 분석 설계를 명확히 이해하려면 둘을 구분하는 편이 낫습니다.
이 글에서는 다음 기준으로 정리합니다.
| 설계 | 이 글에서의 명칭 | 핵심 구조 |
|---|---|---|
| 반복측정 요인 1개 | 반복측정 분산분석 | within 1개 |
| 반복측정 요인 2개 | 이원 반복측정 분산분석 | within 2개 |
| 독립집단 요인 1개 + 반복측정 요인 1개 | Mixed ANOVA | between 1개 + within 1개 |
이 구분을 잡아 두면 뒤에서 within, between, wid, sphericity 같은 용어도 훨씬 자연스럽게 이해됩니다.

ANOVA 계열을 이해하기 전에 알아야 할 공통 개념
1. 주효과와 상호작용
ANOVA 계열에서 가장 자주 나오는 두 단어는 주효과(main effect)와 상호작용(interaction)입니다.
- 주효과: 어떤 요인이 다른 요인을 무시하고 보더라도 평균 차이를 만드는가
- 상호작용: 한 요인의 효과가 다른 요인의 수준에 따라 달라지는가
예를 들어 교육방법(온라인, 오프라인)과 시간(사전, 사후)이 있다고 합시다.
- 교육방법 주효과: 전반적으로 온라인과 오프라인 평균이 다른가
- 시간 주효과: 전반적으로 사전과 사후 평균이 다른가
- 상호작용: 온라인에서는 점수가 많이 오르지만 오프라인에서는 거의 안 오르는가
상호작용이 유의하면, 주효과만 읽고 끝내면 해석이 틀어질 수 있습니다. 그래서 이원 ANOVA 이후부터는 상호작용 해석이 핵심입니다.
2. within-subject와 between-subject
| 구분 | 뜻 | 예시 |
|---|---|---|
| between-subject factor | 서로 다른 사람이 서로 다른 집단에 속함 | 성별, 처치군, 학교 유형 |
| within-subject factor | 같은 사람에게 반복 측정함 | 시간, 조건, 과제 유형 |
이 차이를 이해해야 반복측정 ANOVA와 Mixed ANOVA를 정확히 구분할 수 있습니다.
3. R에서 자주 쓰는 함수
| 함수 | 용도 |
|---|---|
aov() |
고전적인 ANOVA 모델 적합 |
anova_test() |
rstatix 기반의 쉬운 ANOVA 인터페이스 |
get_anova_table() |
anova_test() 결과를 표 형태로 추출 |
TukeyHSD() |
일원/이원 ANOVA의 사후검정 |
pairwise_t_test() |
반복측정 또는 그룹별 쌍대비교 |
emmeans_test() / emmeans() |
보정평균, 사후비교, 단순효과 분석 |
manova() |
다변량 분산분석 |
실무에서는 aov()와 rstatix::anova_test()를 모두 볼 줄 아는 편이 좋습니다. aov()는 base R이라 범용적이고, anova_test()는 반복측정 설계를 다룰 때 훨씬 편합니다.
1. 일원 분산분석(one-way ANOVA)
언제 쓰는가
일원 분산분석은 가장 기본적인 평균 비교 모델입니다.
- 종속변수는 수치형 1개
- 독립변수는 범주형 1개
- 그룹 수는 3개 이상
- 각 그룹은 서로 독립
예를 들어 세 가지 치료법 A, B, C의 평균 효과를 비교하고 싶을 때 사용합니다.
귀무가설과 대립가설
H0: 모든 집단 평균은 같다H1: 적어도 한 집단 평균은 다르다
여기서 중요합니다. ANOVA가 유의하다고 해서 “모든 그룹이 서로 다르다”는 뜻은 아닙니다. 정확한 의미는 최소 한 쌍 이상 차이가 있다입니다.
예제: PlantGrowth
# install.packages(c("rstatix", "ggpubr"))
data(PlantGrowth)
str(PlantGrowth)
fit_oneway <- aov(weight ~ group, data = PlantGrowth)
summary(fit_oneway)코드 해설
weight: 종속변수group: 세 집단(ctrl,trt1,trt2)을 나타내는 독립변수aov(weight ~ group): 그룹에 따라 평균 체중이 달라지는지 검정summary(): F값과 p-value를 포함한 ANOVA 표 출력
해석 포인트
일원 분산분석에서는 먼저 아래를 봅니다.
Df: 자유도Sum Sq: 제곱합Mean Sq: 평균제곱F value: 집단 간 변동 / 집단 내 변동Pr(>F): p-value
p-value가 0.05보다 작으면 적어도 한 집단 평균은 다르다고 해석합니다.
가정 점검
1) 독립성
데이터 수집 설계에서 보장해야 합니다. 같은 사람을 여러 번 측정했다면 일원 ANOVA가 아니라 반복측정 ANOVA 쪽으로 가야 합니다.
2) 정규성
엄밀히는 잔차의 정규성을 봅니다.
shapiro.test(residuals(fit_oneway))
qqnorm(residuals(fit_oneway))
qqline(residuals(fit_oneway))3) 등분산성
bartlett.test(weight ~ group, data = PlantGrowth)
fligner.test(weight ~ group, data = PlantGrowth)bartlett.test()는 정규성에 민감합니다.fligner.test()는 비교적 강건합니다.
사후검정
ANOVA가 유의하면 어느 그룹끼리 차이가 나는지 봐야 합니다.
TukeyHSD(fit_oneway)왜 TukeyHSD를 쓰는가
그룹이 여러 개일 때 pairwise t-test를 반복하면 1종 오류가 커집니다. TukeyHSD()는 이 다중비교 문제를 조정해 줍니다.
효과 크기
p-value만 보면 “유의한가 아닌가”만 알 수 있습니다. 얼마나 큰 차이인지는 eta squared 같은 효과 크기를 함께 보는 편이 낫습니다.
# install.packages("effectsize")
effectsize::eta_squared(fit_oneway)2. 반복측정 분산분석(repeated measures ANOVA)
언제 쓰는가
반복측정 분산분석은 같은 사람을 여러 번 측정했을 때 사용합니다.
- 종속변수는 수치형 1개
- 반복측정 요인(within factor) 1개
- 같은 피험자에게 여러 시점 또는 여러 조건을 적용
예를 들어 같은 학생의 점수를 사전, 중간, 사후 세 번 측정했다면 반복측정 분산분석이 적합합니다.
왜 일원 ANOVA를 쓰면 안 되는가
같은 사람의 측정값은 서로 독립이 아닙니다. 일원 ANOVA는 관측치 독립성을 기본 전제로 하기 때문에, 반복측정 자료에 그대로 적용하면 구조를 잘못 모델링하게 됩니다.
예제: 한 집단을 3시점에서 반복 측정한 경우
아래 코드는 설명용 시뮬레이션 예제입니다.
set.seed(123)
subject_effect <- rnorm(18, 0, 5)
rm1 <- tidyr::expand_grid(
id = factor(1:18),
time = factor(c("pre", "mid", "post"), levels = c("pre", "mid", "post"))
) |>
dplyr::mutate(
person = rep(subject_effect, each = 3),
score = 60 + person +
dplyr::case_when(
time == "pre" ~ 0,
time == "mid" ~ 4,
time == "post" ~ 9
) +
rnorm(dplyr::n(), 0, 2)
) |>
dplyr::select(-person)
res_rm1 <- rstatix::anova_test(
data = rm1,
dv = score,
wid = id,
within = time
)
rstatix::get_anova_table(res_rm1)인수 설명
data: long format 데이터프레임dv: 종속변수 이름wid: 피험자 IDwithin: 반복측정 요인 이름
반복측정 ANOVA에서는 wid가 매우 중요합니다. 어느 관측치가 같은 사람에게서 나온 값인지를 R이 알아야 하기 때문입니다.
구형성(sphericity)
반복측정 요인이 3수준 이상이면 구형성이 중요한 가정이 됩니다.
- 시점 간 차이의 분산이 비슷해야 한다는 조건
- 위반되면 F검정이 지나치게 낙관적일 수 있음
anova_test()는 Mauchly 검정을 수행하고, 필요하면 Greenhouse-Geisser 보정을 자동 적용합니다.
rstatix::get_anova_table(res_rm1)실무 해석
Mauchly's Test가 유의하지 않으면 보통 원래 결과를 읽습니다.- 유의하면 구형성 위반 가능성이 있으므로
GG correction이나HF correction결과를 봅니다.
사후비교
rm1 |>
rstatix::pairwise_t_test(
score ~ time,
paired = TRUE,
p.adjust.method = "bonferroni"
)paired = TRUE를 반드시 확인해야 합니다. 같은 사람을 반복 측정했기 때문입니다.
언제 선형혼합모형을 고려해야 하는가
반복측정 ANOVA는 균형 잡힌 자료와 완전한 케이스에 비교적 잘 맞습니다. 결측이 많거나 시점 간 간격이 불규칙하면 lme4, nlme 같은 혼합효과모형이 더 적합할 수 있습니다.
3. 이원 분산분석(two-way ANOVA)
언제 쓰는가
이원 분산분석은 독립변수가 두 개일 때 사용합니다.
- 종속변수는 수치형 1개
- 독립변수는 범주형 2개
- 두 요인 모두 between-subject 구조
예를 들어 보충제 종류(supp)와 복용량(dose)가 치아 길이(len)에 미치는 영향을 동시에 보고 싶다면 이원 ANOVA를 쓸 수 있습니다.
예제: ToothGrowth
ToothGrowth2 <- ToothGrowth |>
dplyr::mutate(dose = factor(dose))
fit_twoway <- aov(len ~ supp * dose, data = ToothGrowth2)
summary(fit_twoway)supp * dose가 의미하는 것
A * B는 아래 세 가지를 한 번에 포함합니다.
A의 주효과B의 주효과A:B상호작용
즉,
len ~ supp * dose는 아래와 같습니다.
len ~ supp + dose + supp:dose무엇을 먼저 해석해야 하나
이원 ANOVA에서는 보통 상호작용부터 봅니다.
- 상호작용이 유의하면: 단순히 주효과만 읽으면 위험합니다.
- 상호작용이 유의하지 않으면: 각 요인의 주효과를 중심으로 읽습니다.
상호작용 시각화
interaction.plot(
x.factor = ToothGrowth2$dose,
trace.factor = ToothGrowth2$supp,
response = ToothGrowth2$len,
xlab = "dose",
ylab = "mean tooth length",
trace.label = "supplement"
)선이 평행하지 않으면 상호작용 가능성을 의심합니다. 물론 최종 판단은 그래프가 아니라 ANOVA 표의 상호작용 항 p-value로 합니다.
사후분석과 단순효과 분석
상호작용이 유의하면 “각 dose 수준에서 supp 차이가 있는가” 또는 “각 supp 수준에서 dose 차이가 있는가”처럼 쪼개서 봐야 합니다.
ToothGrowth2 |>
dplyr::group_by(dose) |>
rstatix::t_test(len ~ supp)
ToothGrowth2 |>
dplyr::group_by(supp) |>
rstatix::anova_test(len ~ dose)왜 전체 Tukey만으로 끝내면 안 되는가
상호작용이 유의하면 전체 평균만 비교하는 사후분석은 맥락을 잃기 쉽습니다. 이때는 단순효과(simple effects)를 우선적으로 읽는 편이 맞습니다.
4. 이원 반복측정 분산분석(two-way repeated measures ANOVA)
언제 쓰는가
이원 반복측정 분산분석은 반복측정 요인이 두 개일 때 사용합니다.
- 종속변수는 수치형 1개
- within factor가 2개
- 같은 사람이 모든 조건 조합을 경험
예를 들어 같은 참가자에게
- 시간:
사전,사후 - 과제난이도:
쉬움,어려움
을 모두 경험하게 하고 점수를 측정했다면 이원 반복측정 분산분석이 맞습니다.
Mixed ANOVA와 무엇이 다른가
여기서는 두 요인 모두 반복측정입니다. 즉 같은 사람이 시간도 바뀌고, 과제 조건도 바뀝니다. Mixed ANOVA는 뒤에서 설명하겠지만, 한 요인은 반복측정이고 다른 한 요인은 집단 요인입니다.
예제 코드
set.seed(123)
subject_random <- rnorm(24, 0, 4)
rm2 <- tidyr::expand_grid(
id = factor(1:24),
time = factor(c("pre", "post"), levels = c("pre", "post")),
task = factor(c("easy", "hard"), levels = c("easy", "hard"))
) |>
dplyr::mutate(
person = rep(subject_random, each = 4),
score = 70 + person +
ifelse(time == "post", 5, 0) +
ifelse(task == "hard", -8, 0) +
ifelse(time == "post" & task == "hard", 3, 0) +
rnorm(dplyr::n(), 0, 3)
) |>
dplyr::select(-person)
res_rm2 <- rstatix::anova_test(
data = rm2,
dv = score,
wid = id,
within = c(time, task)
)
rstatix::get_anova_table(res_rm2)인수 설명
within = c(time, task): 반복측정 요인이 두 개라는 뜻wid = id: 같은 참가자의 여러 행이 하나의 사람이라는 뜻
해석 포인트
이 모델에서는 세 가지를 봅니다.
time주효과task주효과time:task상호작용
예를 들어 time:task 상호작용이 유의하다면, 사후에 점수가 오르긴 했지만 그 상승폭이 쉬운 과제와 어려운 과제에서 다르다고 해석할 수 있습니다.
사후비교 예시
rm2 |>
dplyr::group_by(task) |>
rstatix::pairwise_t_test(
score ~ time,
paired = TRUE,
p.adjust.method = "bonferroni"
)
rm2 |>
dplyr::group_by(time) |>
rstatix::pairwise_t_test(
score ~ task,
paired = TRUE,
p.adjust.method = "bonferroni"
)이런 방식으로 각 수준별 단순효과를 확인합니다.
5. Mixed ANOVA
언제 쓰는가
Mixed ANOVA는 가장 자주 헷갈리는 설계 중 하나입니다. 핵심은 다음입니다.
- between-subject 요인 1개 이상
- within-subject 요인 1개 이상
- 즉, 집단 차이와 시간 변화가 동시에 존재
대표 예시는 아래와 같습니다.
- 집단: 대조군 vs 치료군
- 시간: 사전, 중간, 사후
- 질문: 시간에 따라 점수 변화가 달라지는데, 그 패턴이 집단마다 다른가
왜 중요한가
단순한 반복측정 ANOVA는 모두 같은 집단 안에서만 시간 변화를 봅니다. Mixed ANOVA는 여기에 집단 효과를 추가해, “누가 더 많이 변했는가”까지 봅니다.
예제: datarium::anxiety
# install.packages(c("datarium", "rstatix", "tidyr", "dplyr"))
data("anxiety", package = "datarium")
anxiety_long <- anxiety |>
tidyr::pivot_longer(
cols = c(t1, t2, t3),
names_to = "time",
values_to = "score"
) |>
dplyr::mutate(
id = factor(id),
time = factor(time, levels = c("t1", "t2", "t3")),
group = factor(group)
)
res_mixed <- rstatix::anova_test(
data = anxiety_long,
dv = score,
wid = id,
within = time,
between = group
)
rstatix::get_anova_table(res_mixed)무엇을 읽어야 하나
Mixed ANOVA의 핵심 출력은 보통 아래 세 항목입니다.
group주효과: 전반적으로 집단 간 평균 차이가 있는가time주효과: 전반적으로 시간에 따라 변화가 있는가group:time상호작용: 시간 변화 패턴이 집단마다 다른가
실무적으로 가장 중요한 것은 group:time입니다. 치료 효과를 보려는 연구에서는 특히 그렇습니다.
가정 점검
# 이상치
anxiety_long |>
dplyr::group_by(group, time) |>
rstatix::identify_outliers(score)
# 정규성
anxiety_long |>
dplyr::group_by(group, time) |>
rstatix::shapiro_test(score)
# 등분산성: between factor 수준별
anxiety_long |>
dplyr::group_by(time) |>
rstatix::levene_test(score ~ group)추가로 기억할 점
- within 요인에 대해 구형성을 봅니다.
- between 요인에 대해서는 등분산성이 중요합니다.
- 자료가 불균형하거나 결측이 많으면 혼합효과모형이 더 안정적일 수 있습니다.
사후분석
상호작용이 유의하면 단순효과 분석을 합니다.
# 각 시점에서 집단 차이
anxiety_long |>
dplyr::group_by(time) |>
rstatix::pairwise_t_test(score ~ group, p.adjust.method = "bonferroni")
# 각 집단 안에서 시간 차이
anxiety_long |>
dplyr::group_by(group) |>
rstatix::pairwise_t_test(
score ~ time,
paired = TRUE,
p.adjust.method = "bonferroni"
)6. MANOVA(다변량 분산분석)
언제 쓰는가
MANOVA는 종속변수가 둘 이상일 때 사용하는 ANOVA 확장입니다.
- 종속변수 2개 이상
- 독립변수는 범주형
- 종속변수들이 서로 관련되어 있음
예를 들어 세 품종의 식물을 비교하는데,
- 키(
height) - 수관 부피(
canopy volume)
를 동시에 보려면 MANOVA가 적합합니다.
왜 ANOVA 여러 번 대신 MANOVA를 쓰는가
단순히 ANOVA를 두 번 돌릴 수도 있습니다. 하지만 그러면 다음 문제가 생깁니다.
- 제1종 오류 누적 가능성
- 종속변수 간 상관구조를 반영하지 못함
MANOVA는 여러 종속변수의 결합된 차이를 한 번에 본다는 점이 핵심입니다.
예제: iris
내장 데이터 iris를 사용하면 가장 빠르게 구조를 이해할 수 있습니다.
fit_manova <- manova(
cbind(Sepal.Length, Petal.Length) ~ Species,
data = iris
)
summary(fit_manova, test = "Pillai")
summary.aov(fit_manova)코드 해설
cbind(Sepal.Length, Petal.Length): 종속변수가 2개라는 뜻Species: 세 종의 붓꽃 집단 비교test = "Pillai": 다변량 검정통계량으로 Pillai’s trace 사용
왜 Pillai’s trace를 많이 쓰는가
MANOVA에는 Wilks, Pillai, Hotelling-Lawley, Roy 등 여러 통계량이 있습니다. 실무에서는 Pillai's trace를 비교적 강건한 선택지로 보는 경우가 많습니다.
MANOVA 후에는 무엇을 하나
MANOVA가 유의하면 그다음은 보통 아래 흐름입니다.
- 어떤 종속변수 조합에서 차이가 있는지 이해
summary.aov()로 개별 종속변수에 대한 후속 ANOVA 확인- 필요하면 사후비교 또는 판별분석(LDA) 수행
# install.packages("MASS")
lda_fit <- MASS::lda(
Species ~ Sepal.Length + Petal.Length,
data = iris
)
lda_fit주요 가정
| 가정 | 설명 |
|---|---|
| 다변량 정규성 | 종속변수 조합이 각 집단에서 대체로 정규 |
| 공분산행렬 동질성 | 집단 간 분산-공분산 구조가 유사 |
| 다중공선성 과도하지 않음 | 종속변수끼리 거의 완전히 중복되면 곤란 |
| 이상치 없음 | 다변량 이상치가 결과를 왜곡할 수 있음 |
Box’s M 검정 예시
# install.packages("heplots")
heplots::boxM(iris[, c("Sepal.Length", "Petal.Length")], iris$Species)MANOVA를 쓰면 좋은 상황
- 결과지표가 여러 개이고 서로 상관이 있다
- 종속변수들을 따로따로 보는 것보다, 전체 패턴을 함께 보고 싶다
- 여러 개의 ANOVA를 반복하는 대신 하나의 다변량 검정을 먼저 하고 싶다
7. ANCOVA(공분산분석)
언제 쓰는가
ANCOVA는 집단 평균 비교를 하되, 수치형 공변량(covariate)의 영향을 보정하고 싶을 때 사용합니다.
예를 들어 치료군과 대조군의 사후 점수를 비교하고 싶은데, 사전 점수 차이가 이미 존재한다면 단순 ANOVA보다 ANCOVA가 더 적절할 수 있습니다.
ANCOVA를 한 문장으로 정리하면
공변량의 영향을 통제한 뒤 집단의 조정평균(adjusted mean)을 비교하는 방법
언제 특히 유용한가
- 사전점수 차이를 보정하고 싶을 때
- 연령, 기초능력, 베이스라인 점수 같은 연속형 변수를 통제하고 싶을 때
- 같은 처치 효과를 더 공정하게 비교하고 싶을 때
예제: 사전점수를 보정한 뒤 집단별 사후점수 비교
# install.packages(c("datarium", "rstatix", "broom", "emmeans"))
data("anxiety", package = "datarium")
ancova_df <- anxiety |>
dplyr::transmute(
id,
group,
pretest = t1,
posttest = t3
)
# 1) 회귀기울기 동질성 확인
ancova_df |>
rstatix::anova_test(posttest ~ group * pretest)
# 2) 상호작용이 유의하지 않으면 ANCOVA 적합
res_ancova <- ancova_df |>
rstatix::anova_test(posttest ~ pretest + group)
rstatix::get_anova_table(res_ancova)가장 중요한 가정: 회귀기울기 동질성
ANCOVA에서는 공변량과 집단의 상호작용이 없어야 합니다. 즉, 공변량이 종속변수에 미치는 기울기가 집단마다 대체로 비슷해야 합니다.
그래서 ANCOVA에서는 아래 순서를 많이 씁니다.
group * covariate상호작용 확인- 상호작용이 유의하지 않으면
covariate + group모델 적합 - group 효과 해석
보정평균(estimated marginal means)
ANCOVA에서 보고 싶은 것은 원시 평균보다 보정평균인 경우가 많습니다.
# install.packages("emmeans")
fit_lm <- lm(posttest ~ pretest + group, data = ancova_df)
emmeans::emmeans(fit_lm, ~ group)사후비교
ancova_df |>
rstatix::emmeans_test(
posttest ~ group,
covariate = pretest,
p.adjust.method = "bonferroni"
)ANCOVA를 사용할 때 주의할 점
- 공변량은 보통 처치 이전에 측정된 변수인 편이 안전합니다.
- 처치의 영향을 이미 받은 변수를 공변량으로 넣으면 해석이 꼬일 수 있습니다.
- ANCOVA는 “잡음을 제거하는 마법”이 아니라, 설계상 타당한 공변량을 통제하는 도구입니다.
8. 각 방법을 어떻게 구분해서 선택할까
한눈에 보는 선택표
| 분석 | 종속변수 수 | 요인 구조 | 대표 질문 |
|---|---|---|---|
| 일원 ANOVA | 1 | between 1개 | 세 집단 이상 평균이 다른가 |
| 반복측정 ANOVA | 1 | within 1개 | 같은 사람의 점수가 시간에 따라 달라지는가 |
| 이원 ANOVA | 1 | between 2개 | 두 요인의 주효과와 상호작용이 있는가 |
| 이원 반복측정 ANOVA | 1 | within 2개 | 두 반복측정 요인의 효과와 상호작용이 있는가 |
| Mixed ANOVA | 1 | between 1개 + within 1개 | 집단별 변화 패턴이 다른가 |
| MANOVA | 2개 이상 | between 중심 | 여러 결과변수의 결합 평균벡터가 다른가 |
| ANCOVA | 1 | between + covariate | 공변량을 보정한 뒤 집단 차이가 있는가 |
이런 순서로 고르면 대부분 맞는다
- 종속변수가 하나인가, 여러 개인가
- 독립변수가 하나인가, 두 개인가
- 같은 사람을 반복 측정했는가
- 공변량을 보정해야 하는가
이 네 가지 질문만으로도 대부분의 선택이 정리됩니다.
9. 공통 가정은 무엇이고, 어디서 달라지는가
| 분석 | 주요 추가 가정 |
|---|---|
| 일원 ANOVA | 정규성, 등분산성, 독립성 |
| 반복측정 ANOVA | 정규성, 구형성, 반복측정 구조 반영 |
| 이원 ANOVA | 정규성, 등분산성, 독립성 |
| 이원 반복측정 ANOVA | 정규성, 구형성, within 요인별 상호작용 구조 |
| Mixed ANOVA | between 쪽 등분산성 + within 쪽 구형성 |
| MANOVA | 다변량 정규성, 공분산행렬 동질성 |
| ANCOVA | 선형성, 회귀기울기 동질성, 잔차 정규성, 등분산성 |
초보자가 많이 놓치는 포인트
- 반복측정 자료를 독립표본 ANOVA에 넣는다
- 상호작용이 유의한데 주효과만 보고 결론을 낸다
- ANCOVA에서 회귀기울기 동질성을 확인하지 않는다
- MANOVA인데 종속변수 간 상관을 전혀 보지 않는다
- 구형성 위반이 있는데 보정된 결과를 보지 않는다
10. 가정이 불안할 때의 대안도 알아야 한다
ANOVA 계열은 강력하지만, 항상 정답은 아닙니다.
일원 ANOVA 대안
- 등분산이 흔들리면:
Welch's ANOVA - 정규성/이상치 문제가 크면:
Kruskal-Wallis test
oneway.test(weight ~ group, data = PlantGrowth, var.equal = FALSE)
kruskal.test(weight ~ group, data = PlantGrowth)반복측정 설계 대안
- 결측이 많다
- 측정 시점이 불균형하다
- 개체별 변화 패턴을 모델링하고 싶다
이런 경우는 linear mixed model이 더 유연합니다.
ANCOVA 대안
공변량과 집단 상호작용이 크면 단순 ANCOVA보다 상호작용 포함 회귀모형이 더 적합할 수 있습니다.
11. 보고서에는 어떻게 쓰면 좋은가
일원 ANOVA 예시 문장
일원 분산분석 결과, 세 그룹 평균에는 유의한 차이가 있었다.
F(2, 27) = 4.85, p = .016.
사후검정에서는 trt2와 trt1 간 차이가 유의했다.
이원 ANOVA 예시 문장
이원 분산분석 결과, 보충제와 복용량 간 상호작용이 유의하였다.
즉, 복용량의 효과는 보충제 종류에 따라 달랐다.
Mixed ANOVA 예시 문장
Mixed ANOVA 결과, 시간과 집단의 상호작용이 유의하였다.
이는 시간에 따른 점수 변화 양상이 집단마다 다름을 의미한다.
ANCOVA 예시 문장
사전점수를 공변량으로 통제한 ANCOVA 결과, 집단 효과는 유의하였다.
즉, 베이스라인 차이를 보정한 뒤에도 집단 간 사후점수 차이가 남아 있었다.
12. 자주 하는 질문
일원 ANOVA와 이원 ANOVA의 가장 큰 차이는 무엇인가
독립변수 개수입니다. 일원 ANOVA는 요인이 1개, 이원 ANOVA는 요인이 2개입니다. 이원 ANOVA부터는 상호작용 해석이 핵심이 됩니다.
반복측정 ANOVA와 paired t-test는 어떤 관계인가
시점이 2개뿐이면 반복측정 ANOVA와 paired t-test는 사실상 같은 정보를 주는 경우가 많습니다. 시점이 3개 이상이면 반복측정 ANOVA가 필요합니다.
Mixed ANOVA와 혼합효과모형은 같은가
아닙니다. 이름은 비슷하지만 다릅니다. Mixed ANOVA는 고전적 분산분석 설계이고, 혼합효과모형은 더 유연한 회귀 기반 프레임입니다.
MANOVA는 언제 꼭 고려할 가치가 있나
종속변수가 여러 개이고, 이 변수들이 서로 관련되어 있으며, 각각 따로 분석하면 정보가 찢어지는 느낌이 들 때 고려할 가치가 큽니다.
ANCOVA에서 공변량은 아무 변수나 넣어도 되나
아닙니다. 해석상 타당한 변수여야 합니다. 보통 처치 이전에 측정된 베이스라인 변수, 연령, 기초능력처럼 결과에 영향을 주지만 관심 주효과와는 개념적으로 구분되는 변수를 씁니다.
13. 마무리
ANOVA 계열은 이름이 복잡해 보여도 결국 하나의 질문에서 출발합니다.
내가 비교하고 싶은 평균 차이는 어떤 설계에서 나온 것인가?
이 질문에 답하면 선택은 생각보다 명확해집니다.
- 집단만 여러 개면 일원 ANOVA
- 같은 사람을 여러 번 보면 반복측정 ANOVA
- 요인이 두 개면 이원 ANOVA
- 두 반복요인이 있으면 이원 반복측정 ANOVA
- 집단 차이와 시간 변화를 같이 보면 Mixed ANOVA
- 결과변수가 여러 개면 MANOVA
- 공변량을 보정해야 하면 ANCOVA
즉, 분산분석은 하나의 기법이 아니라 설계에 맞춰 골라 쓰는 분석군으로 이해하는 것이 정확합니다.
공식 문서 및 참고 링크
이 글은 이해를 돕기 위해 설계 중심으로 풀어썼지만, 실제 분석에서는 함수 문서와 함께 보는 편이 좋습니다. 특히 aov(), manova(), TukeyHSD()는 base R 문서를, 반복측정 쪽은 rstatix나 emmeans 문서를 같이 보는 것이 실무적으로 유용합니다.
- R
aov()공식 문서: https://stat.ethz.ch/R-manual/R-devel/library/stats/html/aov.html - R
manova()공식 문서: https://stat.ethz.ch/R-manual/R-devel/library/stats/html/manova.html - R
TukeyHSD()공식 문서: https://stat.ethz.ch/R-manual/R-devel/library/stats/html/TukeyHSD.html rstatix패키지 안내: https://cran.r-project.org/package=rstatixemmeans패키지 안내: https://cran.r-project.org/package=emmeans