R 연속형 변수 (2) 그룹별(요인별) 요약통계 비교하기 : tapply(var, factor, summary), by(), aggregate(), summaryBy(), describeBy()
이전 포스팅에서 연속형 변수(continuous variable)의 중심화 경향(central tendancy), 퍼짐 정도(dispersion), 분포형태 및 대칭정도 (distribution and symmetry) 등의 R 함수에 대해 알아보았습니다.
R에서는 이들 개별 통계량에 대해 개별 R 함수를 제공함과 동시에, 참 편리하게도 한방에(!) 연속형 변수의 기술통계량을 볼 수 있게 해주는 함수들이 있는데요,
: summary(), stat.desc(), describe()
(2) 연속형 변수 그룹별(요인별) 요약통계 비교하기
: tapply(var, factor, summary), aggregate(), summaryBy(), describe.by()
중에서 이번에는 R을 이용한 (2) 연속형 변수 그룹별(요인별) 요약통계 비교하기를 소개하겠습니다.
[ 연속형 변수 요약통계 한번에 보기 package & function 요약 ]
category |
package |
function |
statistics |
(1) descriptive statistics summary |
base |
summary() |
min, 1Q, median, mean, 3Q, max |
pastecs |
stat.desc() |
nbr.val, nbr.null, nbr.na, min, max, range, sum, median, mean, var, std.dev, coef.var, skewness, kurtosis, normtest.W, normtest.p, SE.mean, CI.mean.p | |
psych |
describe() |
n, mean, std.dev, median, trimmed, mad, min, max, range, skew, kurtosis, se | |
(2) descriptive statistics comparison by group (factor) |
base |
tapply(var, factor, summary) |
summary: min, 1Q, median, mean, 3Q, max, (user defined) functions... |
base |
by() |
(user defined) functions... | |
stats |
aggregate() |
(user defined) functions... | |
doBy |
summaryBy() |
(user defined) functions... | |
psych |
describeBy() |
n, mean, sd, median, trimmed, mad, min, max, range, skew, kurtosis, se |
MASS package 내 Cars93 데이터프레임의 차종(Type)별 가격(Price), 고속도로연비(MPG.highway) 연속형 변수에 대해서 요약통계를 계산해보겠습니다.
> library(MASS) > str(Cars93) 'data.frame': 93 obs. of 27 variables: $ Manufacturer : Factor w/ 32 levels "Acura","Audi",..: 1 1 2 2 3 4 4 4 4 5 ... $ Model : Factor w/ 93 levels "100","190E","240",..: 49 56 9 1 6 24 54 74 73 35 ... $ Type : Factor w/ 6 levels "Compact","Large",..: 4 3 1 3 3 3 2 2 3 2 ... $ Min.Price : num 12.9 29.2 25.9 30.8 23.7 14.2 19.9 22.6 26.3 33 ... $ Price : num 15.9 33.9 29.1 37.7 30 15.7 20.8 23.7 26.3 34.7 ... $ Max.Price : num 18.8 38.7 32.3 44.6 36.2 17.3 21.7 24.9 26.3 36.3 ... $ MPG.city : int 25 18 20 19 22 22 19 16 19 16 ... $ MPG.highway : int 31 25 26 26 30 31 28 25 27 25 ... $ AirBags : Factor w/ 3 levels "Driver & Passenger",..: 3 1 2 1 2 2 2 2 2 2 ... $ DriveTrain : Factor w/ 3 levels "4WD","Front",..: 2 2 2 2 3 2 2 3 2 2 ... $ Cylinders : Factor w/ 6 levels "3","4","5","6",..: 2 4 4 4 2 2 4 4 4 5 ... $ EngineSize : num 1.8 3.2 2.8 2.8 3.5 2.2 3.8 5.7 3.8 4.9 ... $ Horsepower : int 140 200 172 172 208 110 170 180 170 200 ... $ RPM : int 6300 5500 5500 5500 5700 5200 4800 4000 4800 4100 ... $ Rev.per.mile : int 2890 2335 2280 2535 2545 2565 1570 1320 1690 1510 ... $ Man.trans.avail : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 1 1 1 1 ... $ Fuel.tank.capacity: num 13.2 18 16.9 21.1 21.1 16.4 18 23 18.8 18 ... $ Passengers : int 5 5 5 6 4 6 6 6 5 6 ... $ Length : int 177 195 180 193 186 189 200 216 198 206 ... $ Wheelbase : int 102 115 102 106 109 105 111 116 108 114 ... $ Width : int 68 71 67 70 69 69 74 78 73 73 ... $ Turn.circle : int 37 38 37 37 39 41 42 45 41 43 ... $ Rear.seat.room : num 26.5 30 28 31 27 28 30.5 30.5 26.5 35 ... $ Luggage.room : int 11 15 14 17 13 16 17 21 14 18 ... $ Weight : int 2705 3560 3375 3405 3640 2880 3470 4105 3495 3620 ... $ Origin : Factor w/ 2 levels "USA","non-USA": 2 2 2 2 2 1 1 1 1 1 ... $ Make : Factor w/ 93 levels "Acura Integra",..: 1 2 4 3 5 6 7 9 8 10 ...
|
각 package별 R 함수 사용예는 아래와 같습니다.
(1) base package : tapply(var, factor, summary)
> with(Cars93, tapply(MPG.highway, Type, summary)) $Compact Min. 1st Qu. Median Mean 3rd Qu. Max. 26 28 30 30 31 36 $Large Min. 1st Qu. Median Mean 3rd Qu. Max. 25 26 26 27 28 28 $Midsize Min. 1st Qu. Median Mean 3rd Qu. Max. 22 25 26 27 29 31 $Small Min. 1st Qu. Median Mean 3rd Qu. Max. 29 33 33 36 37 50 $Sporty Min. 1st Qu. Median Mean 3rd Qu. Max. 24 25 28 29 31 36 $Van Min. 1st Qu. Median Mean 3rd Qu. Max. 20 21 22 22 23 24 |
tapply함수를 사용해서 특정 변수에 요인(factor)별 summary()함수를 적용하였습니다. 가격(Price)과 고속도로연비(MPG.highway) 를 한꺼번에 못하고 두번에 나누어서 적용해야 하며, 제시된 포맷도 일괄 비교해서 보기에는 조금 불편한 점이 있습니다.
(2) base package : by()
|
두번째는 base package의 by()함수를 사용하는 방법인데요, 위의 예에서는 관측값 개수 n, 평균 mean, 표준편차 sd 를 그룹(요인)별로 일괄 계산하는 script가 되겠습니다.
by() 함수는 두 개 이상의 기술통계량을 그룹(요인)별로 계산하고 싶다면 사용자 정의 함수(user defined function)를 미리 만들어놓아야 하며, by() 함수 내에 sapply()를 적용해야 하므로 초보자가 이용하기에는 어려운 방법이 되겠습니다. 너무 복잡해서 외우기도 사실상 어렵습니다. -_-;
사용자 정의함수에서 '...' 은 '결측값 제거 후 계산'과 같은 추가 옵션을 설정할 수 있도록 하는 명령문입니다.
(3) stats package : aggregate()
> ##-- (3) stats package : aggregate() > library(stats) > fun_summary_2 <- function(x, ...) { + c(n=sum(!is.na(x)), mean=mean(x, ...), sd=sd(x, ...)) + } > > aggregate(Cars93[c("Price", "MPG.highway")], # dataset$variable + by=list(Car_Type=Cars93$Type), # by Group(Factor) + fun_summary_2, na.rm=T) # function Car_Type Price.n Price.mean Price.sd MPG.highway.n MPG.highway.mean MPG.highway.sd 1 Compact 16.0 18.2 6.7 16.0 29.9 2.9 2 Large 11.0 24.3 6.3 11.0 26.7 1.3 3 Midsize 22.0 27.2 12.3 22.0 26.7 2.5 4 Small 21.0 10.2 2.0 21.0 35.5 5.6 5 Sporty 14.0 19.4 8.0 14.0 28.8 3.6 6 Van 9.0 19.1 1.9 9.0 21.9 1.5
|
세번째로, stats package의 aggregate() 함수는 그룹(요인) 자리에 list() 로 들어가며, by()함수처럼 두개 이상의 통계량을 보려면 사용자 정의 함수를 미리 만들어서 사용해야 하므로 초보자에게 역시 쉽지 않습니다.
통계량들이 제시되는 포맷이 tapply(summary), by()와는 달리, 위에서 보는 것처럼 row에 그룹(요인)이 위치하고 column에 각 통계량들이 나열되어 있습니다.
(4) doBy package : summaryBy()
> ##-- (4) doBy package : summaryBy() > install.packages("doBy") Installing package into ‘C:/Users/user/Documents/R/win-library/3.2’ (as ‘lib’ is unspecified) trying URL 'http://cran.rstudio.com/bin/windows/contrib/3.2/doBy_4.5-13.zip' Content type 'application/zip' length 3431577 bytes (3.3 MB) downloaded 3.3 MB package ‘doBy’ successfully unpacked and MD5 sums checked The downloaded binary packages are in C:\Users\user\AppData\Local\Temp\RtmpqgHvNR\downloaded_packages > library(doBy) 필요한 패키지를 로딩중입니다: survival > > > summaryBy(Price + MPG.highway ~ Type, data=Cars93, FUN=c(mean, sd))
Type Price.mean MPG.highway.mean Price.sd MPG.highway.sd
1 Compact 18 30 6.7 2.9
2 Large 24 27 6.3 1.3
3 Midsize 27 27 12.3 2.5
4 Small 10 35 2.0 5.6
5 Sporty 19 29 8.0 3.6
6 Van 19 22 1.9 1.5
|
네번째로 doBy package의 summaryBy() 함수는 기본 표현법이 summaryBy( var1 + var2 ~ factor, data, FUN=c(,,)) 으로서 초보자도 사용하기에 매우 쉽고 직관적으로 되어있습니다. 분석결과가 제시되는 포맷도 row에 그룹(요인)이 오고 column에 기초통계량이 와서 일목요연하게 그룹 간 비교하기가 편하게 되어있어서 제가 제일 선호하는 함수입니다.
(5) psych package : describe.by()
|
마지막으로 psych package의 describeBy() 함수의 경우 분석가가 임으로 요약통계량을 지정할 수 없게 되어있으며, describe()함수에서 제시되었던 요약통계량들(n, mean, sd, median, trimmed mean, mad, min, max, range, skewness, kurtosis, se 등)이 자동으로 그룹별로 제시됩니다.
mat=FALSE 옵션을 설정하면 list 형식으로 결과가 제시되며, mat=TRUE 옵션을 지정하면 matrix 형식으로 결과가 나타납니다.
위의 package별 function별 제공하는 요약통계량과 제시 포맷을 참고해서 필요로 하는 방법을 찾아서 사용하기 바랍니다.
많은 도움 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱 눌러주세요. ^^