목표

우리가 그리고자 하는 그래프는 다음과 같은 그래프이다. 에러바가 있는 barplot과 에러바가 있는 lineplot를 그려서 두개를 합치고 A,B로 마킹하는 plot이다.

alt text

데이타 불러오기

이 글에 있는 내용 중 summarySE 함수는 Winston Chang의 R Graphics Cookbook에 있는 내용을 약간 수정한 것임을 밝혀둔다.

먼저 예제에 사용할 데이타는 car 패키지에 있는 Salaries 데이타를 사용하겠다.

require(car)      # 데이타 Salaries 사용하기 위해
require(ggplot2)  # ggplot()을 사용하기 위해
require(plyr)    # ddply() 함수의 사용을 위해

Salaries 데이타는 미국의 조교수,부교수,교수의 월급에 관한 데이타로 모두 397개의 자료이며 한 자료당 6개의 변수가 있다.

str(Salaries)
'data.frame':   397 obs. of  6 variables:
 $ rank         : Factor w/ 3 levels "AsstProf","AssocProf",..: 3 3 1 3 3 2 3 3 3 3 ...
 $ discipline   : Factor w/ 2 levels "A","B": 2 2 2 2 2 2 2 2 2 2 ...
 $ yrs.since.phd: int  19 20 4 45 40 6 30 45 21 18 ...
 $ yrs.service  : int  18 16 3 39 41 6 23 45 20 18 ...
 $ sex          : Factor w/ 2 levels "Female","Male": 2 2 2 2 2 2 2 2 2 1 ...
 $ salary       : int  139750 173200 79750 115000 141500 97000 175000 147765 119250 129000 ...
head(Salaries)
       rank discipline yrs.since.phd yrs.service  sex salary
1      Prof          B            19          18 Male 139750
2      Prof          B            20          16 Male 173200
3  AsstProf          B             4           3 Male  79750
4      Prof          B            45          39 Male 115000
5      Prof          B            40          41 Male 141500
6 AssocProf          B             6           6 Male  97000
summary(Salaries)
        rank     discipline yrs.since.phd    yrs.service        sex     
 AsstProf : 67   A:181      Min.   : 1.00   Min.   : 0.00   Female: 39  
 AssocProf: 64   B:216      1st Qu.:12.00   1st Qu.: 7.00   Male  :358  
 Prof     :266              Median :21.00   Median :16.00               
                            Mean   :22.31   Mean   :17.61               
                            3rd Qu.:32.00   3rd Qu.:27.00               
                            Max.   :56.00   Max.   :60.00               
     salary      
 Min.   : 57800  
 1st Qu.: 91000  
 Median :107300  
 Mean   :113706  
 3rd Qu.:134185  
 Max.   :231545  

R의 표준 방법

이때 ggplot2에 있는 geom_errorbar 함수를 사용하여 그림을 그릴 수가 있는데 이 함수를 쓰려면 plot을 그리기 전 미리 y축 변수의 표준오차 및 신뢰구간을 구하여야 한다. 표준오차는 표준편차를 표본크기의 제곱근으로 나눈 것이다. 예를 들면 Salaries 자료에서 직급(rank)과 성별(sex)에 따른의 연봉(salary)의 평균, 표준편차, 표준오차를 구하려면 다음과 같이 하면 된다.

df=ddply(Salaries,c("rank","sex"),summarise,mean=mean(salary),sd=sd(salary),n=length(salary),se=sd/sqrt(n))
colnames(df)[3]="salary"
df
       rank    sex    salary        sd   n       se
1  AsstProf Female  78049.91  9371.996  11 2825.763
2  AsstProf   Male  81311.46  7901.343  56 1055.861
3 AssocProf Female  88512.80 17965.286  10 5681.122
4 AssocProf   Male  94869.70 12890.817  54 1754.218
5      Prof Female 121967.61 19619.583  18 4624.380
6      Prof   Male 127120.82 28213.808 248 1791.579

이제 이 함수를 가지고 그림을 그리면 된다. 다음과 같이 하면 된다.

p<-ggplot(df,aes(x=rank,y=salary,fill=sex))
  
p1=p+geom_bar(stat="identity",position="dodge")+
  geom_errorbar(aes(ymin=salary-se,ymax=salary+se),
                position="dodge",width=0.2)
p1

하지만 bar의 위치와 errorbar의 위치가 잘 안맞는다. 그 이유는 geom_bar의 경우 position=“dodge”를 사용하면 position_dodge(0.9)로 변환되지만 geom_error는 position_dodge(0.2)로 바뀌기 때문이다. 따라서 bar의 위치와 error_bar의 위치를 맞추어 주려면 position_dodge(0.9)로 맞추어 주어야 한다.

p2=p+geom_bar(stat="identity",position="dodge")+
  geom_errorbar(aes(ymin=salary-se,ymax=salary+se),
                position=position_dodge(0.9),width=0.2)
p2

하지만 line 그래프의 경우는 다르다. 점과 선으로 된 그래프를 그려보면 다음과 같다.

p3=ggplot(df,aes(x=rank,y=salary,group=sex,color=sex))
p4=p3+geom_point(position="dodge")+
  geom_line(position="dodge")+
  geom_errorbar(aes(ymin=salary-se,ymax=salary+se),
                position="dodge",width=0.2)
p4
## ymax not defined: adjusting position using y instead
## ymax not defined: adjusting position using y instead

geom_point와 geom_line은 position=“dodge”로 지정해도 위치가 바뀌지 않기 때문에 position_dodge(0.2)로 바꾸어 주어야 한다.

p5=p3+geom_point(position=position_dodge(0.2))+
  geom_line(position=position_dodge(0.2))
p5+geom_errorbar(aes(ymin=salary-se,ymax=salary+se),
                position="dodge",width=0.2)
## ymax not defined: adjusting position using y instead
## ymax not defined: adjusting position using y instead