본문 바로가기

깜신의 통계 이야기

두 그룹의 평균을 비교하기

두 그룹의 평균을 비교하기











두 그룹의 평균을 비교하는 일은 거창한 연구가 아니더라도, 정말 자주 활용하는 통계분석입니다. 하지만 이것 마저도 처음에는 쉽지 않죠. 저는 오히려 이것까지만 제대로 따라오시면 나머지도 쉽다고 말씀드리고 싶군요. 두 그룹의 평균을 비교하는 통계분석 방법은 전세계에 딱 3개만 있다고 생각하시면 됩니다. 그중 하나가 t-test고요. 다음 하나는 Wilcoxon rank-sum test , 마지막 하나가 Welch’s test입니다. 다른 통계책을 함께 펼쳐 놓고 공부하다가 Mann-Whitney U test와 Mann Whitney-Wilcoxon(MWW) test라는 이름의 분석 방법을 만나실 수도 있는데요. 이 방법들은 모두 Wilcoxon rank-sum test랑 같은 분석이니 당황하실 필요 없습니다. 여러분은 이제 두 그룹의 평균을 비교할 때, 앞서 이야기한 딱 3가지 방법만 머리에 떠올리시면 됩니다. 그렇다면 3가지 방법 중에서 어떤 방법을 써야할까요?

제가 통계를 제대로 공부하기 전에는 통계방법이 해마다 업데이트가 되는 줄 알았습니다. 그래서 제가 대학교 다닐 때 배운 구닥다리 방법으로 의미 있는 p값을 찾지 못할 때, 다른 연구자들은 최신의 통계방법을 사용하여 비슷한 데이터로도 더 작은 p값을 뽑아내는 줄 알았지요. 하지만 막상 통계를 공부해보니, 전혀 그렇지 않더군요. 평균을 비교하는 방법은 예나 지금이나 이렇게 딱 3가지뿐 입니다. 그러니 이 챕터를 공부하고 나시면 여러분은 이제 전세계에서 평균을 가장 잘 비교하지는 못해도, 절대 두 번째가 되지는 않으실 겁니다.

3가지 중 하나를 선택하는 요령



위의 순서도를 보시고, 차근차근 따라하시면 됩니다. 가장 먼저 여러분의 데이터에서 눈여겨 보아야할 부분은 비교하고자 하는 결과값이 연속형 변수냐, 아니냐 입니다. 연속형 변수란 수량화가 가능한 값을 말합니다. AST, ALT등의 간수치나 키, 몸무게 등이 모두 연속형 변수이지요. 나이는 그럼 연속형 변수일까요, 아닐까요? 나이는 대부분 연속형 변수입니다. 하지만 국민건강보험공단이나 심평원에서 배포하는 보건빅데이터에는 나이가 단순한 숫자가 아닌 연령대로 구분되어 있죠. 10대, 20대, 30대로 구분된 데이터라면 이건 더이상 연속형 변수가 아닙니다. 혼란스러우시죠? 제가 다시 정리해드리겠습니다.




모든 데이터는 위 그림에서 보시는 것처럼 범주형 변수와 연속형 변수로 나뉩니다. 그리고 범주형 변수는 다시 명목척도와 순위척도로 구분되죠. 연속형 변수는 간격척도와 비율척도로 또다시 세분화 되고요. 명목척도는 성별이나 직업, 학력, 거주지 등의 변수를 말합니다. 순위척도는 서열척도라고도 자주 불리는데, 설문지에서 대게 많이 등장하죠. 나쁨, 보통, 좋음 등 명목척도 같지만 변수 사이에 순위(서열)가 존재하는 경우가 여기에 해당합니다. 취소선으로 처리된 부분은 궁금한 분만 읽으시면 됩니다. 나머지 분들은 그냥 넘어가도 전혀 문제가 되지 않습니다. 간격척도는 정수로 딱 떨어지는 값들인 경우입니다. 가장 대표적인 간격척도는 사람 수를 셀 때입니다. 학생수나, 입원 환자수등을 셀 때는 정수 밑으로 나눠 셀 수가 없죠. 이에 반해서 비율척도는 소숫점 밑으로 나눠 셀 수 있는 모든 값들이 해당합니다. 신장이나 나이, 체중, 거리, 간수치 등이 모두 여기에 포함되죠. 자, 그럼 연령대는 연속형 변수일까요, 아닐까요? 당연히 범주형 변수안에 포함되는 순위척도입니다. 나이를 ’연령’으로 분석할 때와 ’연령대’로 분석하는 경우는 통계분석 방법이 완전히 다르니 잘 염두해두셔야 합니다.

그럼, 다시 순서도를 살펴보도록 하겠습니다. 연속변수가 아니라면, Wilcoxon signed rank test로 비교를 해야겠군요. 만약, 결과값이 연속형 변수라면 순서도를 따라 밑으로 내려가서 분포가 정규분포인지 아닌지를 다시 살펴야합니다. 만약, 정규분포를 하지 않는다면, 여전히 Wilcoxon signed rank test로 분석을 해야겠군요. 하지만 정규분포를 한다면 한단계를 더 거쳐야합니다. 비교하고자 하는 두 그룹의 분산이 서로 동일한지 그렇지 않은지에 따라 분석 방법이 달라지기 때문입니다. 만약, 두 그룹이 등분산을 만족한다면 그 유명한 Student t test(간혹, independent t test나 단순히 t-test라고 불리기도 합니다.)로 분석을 하게 됩니다. 등분산을 만족하지 못한다면, 대신 Welch’s test라는 다소 낯선 분석 방법이 필요하죠.


이제 어떤 경우에 세 가지 분석 방법 중 하나를 골라야하는지 알아봤으니, 각각의 분석방법을 R스튜디오에서 따라하는 방식으로 함께해보겠습니다.

실습할 예제 데이터 불러오기

오늘 실습에 사용할 데이터는 meanData라는 이름의 데이터셋이고요. 총 41명 학생의 성적이 입력되어 있습니다. 아래 명령어를 R script창에 입력하고 ctl + return(or enter) 키조합 (맥의 경우 cmd + return)을 누르시면 해당 데이터셋이 우측 상단의 Global Environment창에 떠오른 걸 확인하실 수 있을 겁니다. 여기까지 잘 따라오셨다면, 실습할 예제데이터를 메모리에 잘 오르신 거에요.

> meanData <- read.csv(file = "./ch04_01.csv", header = TRUE)



이 다음에 할 일은 meanData에 어떤 데이터들이 들어 있는지 직접 확인해보는 일입니다.

> head(meanData)
  group age sex score
1     1  32   1     7
2     2  56   1    38
3     2  44   1    70
4     1  52   2     6
5     2  24   1    80
6     2  25   1     0

여기서 head()라는 함수는 데이터셋안에서 상단에 있는 6개의 줄(행)을 보여달라는 명령입니다. 작은 데이터를 다룰 때는 View(데이터셋이름) 함수를 이용해서 전체 데이터를 살펴보는 게 도움이 될 수 있지만, 몇 만줄이 넘어가면 되도록 head()함수로 데이터를 살펴볼 것을 권합니다. 컴퓨터가 부담스러워하거든요. 여기서 meanData 데이터셋은 총 41줄 밖에 되지 않는 데이터이니, View(meanData) 명령어를 이용해서 전체 데이터셋을 열어보셔도 됩니다. 물론, 지면 관계상 전체 데이터를 책에 담지는 않겠습니다.

> View(meanData)



> #아마 새 탭이 열리면서, meanData 데이터셋의 로데이터가 모두 보이실 겁니다. 
  이창은 그냥 '미리보기'창이라고 생각하시면 됩니다. R을 처음 쓰기 시작했던 시기에 
  데이터필업 당시 잘못 입력된 값이 있어서 이 창에서 수정을 시도했었는데요. 
  이창에서는 수정은 불가능합니다. 없는 기능이니 굳이 찾는 수고는 따라하지마세요.



전체 데이터를 살펴보시면, 컬럼이 group, age, sex, score 로 구분되어 있습니다. 두 그룹을 비교하기 위한 예제이니, group은 1과 2로 나뉘어져 있고요. age와 score가 연속형 변수로 들어가 있고, sex는 남자는 ’1’로 여자는 ’2’인 명목변수로 채워져 있습니다.



정규분포 여부를 확인하는 방법

이제 순서도의 구석구석을 채우고 있는 여러 과정을 개별적으로 살펴보도록 하겠습니다. 가장 먼저 정규분포 유무를 확인하는 방법입니다. 정규분포의 유무는 아래 코드를 사용해서 확인하게 됩니다.

> # output = lm( 종속변수(결과값) ~ 독립변수(차이의 원인이 되는 값), data= 데이터셋 이름)
> shapiro.test(resid(output))

여기에다가 예제데이터를 적용시키면 아래와 같습니다.

> output = lm(score ~ group, data=meanData)
> shapiro.test(resid(output))

    Shapiro-Wilk normality test

data:  resid(output)
W = 0.91524, p-value = 0.004821

p값이 0.004821로 계산된 게 보이시나요? p값이 0.05보다 크다면 정규분포를 한다고 보고, 0.05보다 작다면 정규분포를 하지 않는다고 기억하시면 됩니다. 이 경우에서는 0.05보다 p값이 한참 작으니까, 데이터의 정규성을 가정할 수 없는 거죠. 참고로, 세 집단을 비교하는 경우에도 똑같이 하시면 되고, 동일하게 p값을 해석하시면 됩니다. 간혹, 정규 분포 유무를 group별로 각각 확인해야하는 거 아니냐는 질문을 받습니다. group ‘1’과 ’2’에 해당하는 각 그룹 사람들의 score가 정규분포를 하는지를 개별적으로 확인하면 안되냐는 거죠. 물론, group별로 정규분포를 하면 위의 p값도 0.05보다 큰 경우가 대부분입니다. 하지만 문제는 두 결과가 일치하지 않을 때 발생합니다. group별 score값의 분포는 정규분포를 하는데, 위 계산에서는 p값이 0.05보다 작을 수도 있거든요. 반대로 group별 score값은 정규분포를 하지 않는데, 위 공식으로 계산한 p값은 0.05보다 클 수도 있습니다. 그렇다면 어떤 결과를 믿어야할까요? 바로 제가 알려드린 공식에서 계산된 p값입니다. 이유는 두 그룹의 평균을 비교하는 분석에서 귀무가설 ’두 그룹의 평균값은 차이가 없다.’에서 출발하기 때문입니다. ’그룹 1의 평균’-‘그룹 2의 평균’ = 0 이라는 현상이 발생할 확률을 계산하는 거죠. 여기서 p값이 0.04으로 계산된다면 평균의 차가 ’0’일 확률이 4% 이므로 자연적으로 발생하기에는 매우 드물다라고 판단하고 ’두 그룹 평균의 차이는 0이 아니다.’라는 대립가설을 받아들이게 되는 겁니다. 이 과정에서 우리가 살펴보는 건 두 그룹간의 차이이지, 각 그룹의 평균이 어떻게 분포하는지가 아닙니다. 그래서 두 집단이든 세 집단이든 정규분포 여부를 확인하는 건, 위에서처럼 lm()함수를 이용해서 얻은 결과값을 resp()함수를 통해 잔차를 계산하고 이 값의 정규성을 shapiro.test()함수를 이용해서 검정하는 게 원론적인 측면에서 더 합당합니다. 물론, 이게 무슨 귀신 씨나락 까먹는 소리냐 싶으신 분들은 그냥 저를 믿고, 위의 방식 때로 정규성 검정을 하시면 됩니다.

등분산인지 확인하는 방법

만약, 정규분포를 만족한다면 순서도에서 다음 과정인 등분산 여부를 확인해야합니다. 등분산을 확인하는 방법은 아래 코드와 같습니다.

> var.test(score~group, data=meanData)

    F test to compare two variances

data:  score by group
F = 0.49629, num df = 19, denom df = 20, p-value = 0.1327
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 0.1999497 1.2451631
sample estimates:
ratio of variances 
           0.49629 

p-value값이 0.1327로 계산된 게 보이시죠? 여기서도 ‘p값이 0.05보다 크면 등분산을 한다’ 고 해석하시면 됩니다. 물론, 0.05보다 작으면 등분산을 하지 않는 거고요. 이제 순서도에서 길목에 해당하는 정규분포와 등분산의 조건을 확인하는 방법을 살펴봤으니, 각각의 경우에서 평균을 비교하는 방법을 알아보도록 하겠습니다.

1) t-test를 하는 방법

세 가지 분석 방법 중 통계의 문턱을 넘어봤다면 모두가 알고 있을 (student’s or independent) t-test부터 살펴보도록 하겠습니다. 결과값이 연속형 변수고, 정규분포를 하면서 등분산까지 한다면 아래 코드로 그룹간의 차이 평균을 비교하시면 됩니다.

> t.test(score~group, data=meanData, var.equal=TRUE)

    Two Sample t-test

data:  score by group
t = -2.9713, df = 39, p-value = 0.005057
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -35.97590  -6.83362
sample estimates:
mean in group 1 mean in group 2 
       14.50000        35.90476 

p값이 0.005057로 나왔네요. 해석은 ‘p값이0.05보다 10배 가까이 작으므로, 두 그룹의 평균은 통계적으로 의미 있게 차이가 난다’고 볼 수 있겠네요. 만약, p값이 0.05보다 크게 나왔다면, 두 그룹의 평균은 차이가 없다고 해석하면 됩니다.

2) Wilcoxon rank sum test를 하는 방법

결과값이 연속형 변수가 아니거나, 정규분포를 하지 않는다면, 아래의 방법으로 분석하면 됩니다. 해당하는 함수의 이름이 wilcox로 시작하니, 기억하기 쉽죠?! 이 방법은 결과값이 정규분포를 하지 않는 경우, 즉 모수라고 가정할 수 없을 때 비모수적인 관점에서 평균을 비교하는 방식입니다. 비모수적 분석에서는 결과값의 순위만 남기고 실제값은 모두 무시합니다. 순위만 가지고 평균을 구해서 두 그룹의 차이를 분석하는 거죠.

> wilcox.test(score~group, data=meanData)
Warning in wilcox.test.default(x = c(7L, 6L, 10L, 65L, 0L, 20L, 0L, 5L, :
cannot compute exact p-value with ties

    Wilcoxon rank sum test with continuity correction

data:  score by group
W = 98.5, p-value = 0.003707
alternative hypothesis: true location shift is not equal to 0

해석은 ‘p값을 기준으로 0.05보다 작으면, 두 그룹의 평균은 통계적으로 의미 있게 차이가 난다’입니다.

결과를 자세히 살펴보시면 warning메세지가 포함된 걸 알 수 있는데요. 똑똑한 wilcox.test()함수가 비모수적인 관점에서 순위(등수)만 가지고 분석을 하려는데, 결과값이 동일한 경우가 많아서(순위가 같은 경우가 있으니) 계산된 p값이 정확한지 자신할 수 없다는 엄살입니다. 결과값 한 두개가 겹치는 일은 실제 분석에서 매우 자주 있으니, 마음쓰지 않으셔도 됩니다.

3) Welch’s test를 하는 방법

마지막으로 결과값이 연속형 변수이고 정규분포는 하는데, 등분산 조건을 만족하지 못하는 경우에 필요한 Welch’s test를 알아보죠. 해당 코드는 아래와 같습니다.

> t.test(score~group, data=meanData, var.equal=FALSE)

    Welch Two Sample t-test

data:  score by group
t = -2.9964, df = 35.988, p-value = 0.004924
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -35.892496  -6.917028
sample estimates:
mean in group 1 mean in group 2 
       14.50000        35.90476 

해석은 마찬가지로 ‘p값이 0.05보다 작으면, 두 그룹의 평균은 통계적으로 의미 있게 차이가 난다’입니다.



두 그룹의 평균을 비교하기 실제

예제데이터의 결과를 순서도를 따라 다시 한 번 확인해보죠. 결과값이 해당하는 score가 연속형 변수이니, 정규분포 여부를 확인해야했고요. 그 결과, 정규분포를 하지 않으니, Wilcoxon rank sum test로 분석해야한다는 결론에 도달했습니다. 2)에 해당하는 코드로 분석한 결과 p값은 0.003707로 두 그룹의 score는 통계적으로 의미 있게 차이가 난다는 결론을 얻을 수 있었죠. 여기서 주의해야할 점은 동일한 데이터를 1)이나 3) 코드에 적용해도 별다른 오류 없이 p값이 계산된다는 겁니다. 올바른 통계 분석 방법을 선택하는 건 결국 저와 여러분의 몫인 거죠. 하지만 걱정하지 마세요. 이곳 제 블로그에 순서도가 있으니까요.