우리가 그리고자 하는 그래프는 다음과 같은 그래프이다. 에러바가 있는 barplot과 에러바가 있는 lineplot를 그려서 두개를 합치고 A,B로 마킹하는 plot이다.
이 글에 있는 내용 중 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
이때 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
위에서 본 ddply함수를 이용하여 표준오차와 표준편차를 구하는 함수는 문제가 있다. 즉 데이타에 누락값이 있으면 동작하지 않는다. 따라서 그런 점을 개선한 함수는 다음과 같다.
summarySE <- function(data=NULL, measurevar, groupvars=NULL,
conf.interval=.95, na.rm=TRUE, .drop=TRUE ) {
require(plyr)
# New version of length that can handle NAs: if na.rm==T, don't count them
length2 <- function (x, na.rm=FALSE) {
if (na.rm) sum(!is.na(x))
else length(x)
}
# This does the summary
datac <- ddply(data, groupvars, .drop=.drop,
.fun = function(xx, col, na.rm) {
c( n = length2(xx[,col], na.rm=na.rm),
mean=mean (xx[,col],na.rm=na.rm),
sd = sd (xx[,col],na.rm=na.rm)
)
},
measurevar,
na.rm
)
# Rename the "mean" column
#datac
colnames(datac)[colnames(datac)=="mean"]=measurevar
#datac <- rename(datac, c("mean" = measurevar))
datac$se <- datac$sd / sqrt(datac$n) # Calculate standard error of the mean
# Confidence interval multiplier for standard error
# Calculate t-statistic for confidence interval:
# e.g., if conf.interval is .95, use .975 (above/below), and use
# df=n-1, or if n==0, use df=0
ciMult <- qt(conf.interval/2 + .5, datac$n-1)
datac$ci <- datac$se * ciMult
return(datac)
}
이 함수는 다음과 같이 사용하면 된다.
df=summarySE(Salaries,"salary",c("sex","rank"))
df
sex rank n salary sd se ci
1 Female AsstProf 11 78049.91 9371.996 2825.763 6296.193
2 Female AssocProf 10 88512.80 17965.286 5681.122 12851.591
3 Female Prof 18 121967.61 19619.583 4624.380 9756.589
4 Male AsstProf 56 81311.46 7901.343 1055.861 2115.993
5 Male AssocProf 54 94869.70 12890.817 1754.218 3518.516
6 Male Prof 248 127120.82 28213.808 1791.579 3528.720
하지만 초보자의 경우 이와 같은 과정을 거쳐 그림을 그리는 것은 무척 어려운 일일 것이다. 따라서 web-r.org에서는 사용자가 ddply함수를 사용하여 데이타를 변환하지 않아도 x축변수, y축변수,group변수, fill변수등을 지정해주고 se, sd자동으로 계산 버튼을 누르면 위와 같은 과정을 거쳐 그래프를 그릴수 있게 해준다.
다음 그림을 보자. web-r.org에 접속하여 로그인 한 후 “웹에서 하는 ggplot2” 샤이니 앱에 들어간 후 잠시 기다린다. default로 Salaries데이타가 선택되어 있다. 표가 보이면 그림과 같이 x축변수, y축변수, fill변수를 선택하고 bar를 클릭하고 stat에는 identity, position은 dodge를 선택한다. 그러면 그림과 같은 errorbar가 없는 barplot이 나온다.
그리고 난후 다음 그림과 같이 errorbar 체크박스를 체크하고 sd, se 자동계산버튼을 누른다.
그러면 다음과 같은 그래프를 얻는다. 화면을 보면 전처리부분에(preprocessing) 내장되어 있는 summarySE함수를 사용하여 se, sd를 자동으로 구하고 그 데이타프레임을 df에 저장하고 df를 불러들여 에러바가 있는 barplot을 완성한 것을 확인할 수 있다.
다음으로 두번째 그래프를 그리기 전에 화면 아래쪽으로 이동해보자. 이 그래프를 그리는데 사용한 R코드와 그래프가 보인다. multiplot으로 저장버튼을 누른다.
두번째 그릴 line plot은 x축 변수가 sex이고 rank에 따라 색깔이 달라진다. 먼저 bar 체크박스를 해제하고 x축 변수에 rank를 선택하고 group변수와 color 변수에 sex를 선택하고 point 체크박스를 체크하고 position에 ’dodge(0.3)’을 선택, line 체크박스를 체크하고 position에 ’dodge(0.3)’을 선택한다. 그림이 약간 이상해보이는데 신경쓰지 말자.
errorbar 체크박스 아래에 있는 position에 0.3을 입력한다.
그림이 그려진 것을 확인하고 Multiplot으로 저장버튼을 누른다.
위쪽의 multiplot 탭을 누른다. 그러면 아래와 같은 화면이 나오는데 plot을 그리는 명령어를 네개 까지 입력할 수 있지만 두개의 plot만 이용한다. 첫번째 plot의 viewport는 default 값이 LUQ(Left Upper Quadrant)로 되어 있다. 즉 화면을 네부분으로 나누었을때 왼쪽 위 사분면에 그림을 넣는다는 뜻이고 두번째 plot은 LLQ 즉 좌하사분면에 위치하게 된다.
또한 화면 아래부분으로 내려가면 plot download 옵션이라는 부분이 있는데 이곳에서 그림의 넓이, 높이, 해상도 등을 선택할 수 있다.
우리는 화면을 세로로 이등분해서 두개의 그림을 위치시킬 것이므로 아래 그림과 같이 첫번째 plot은 left 를 선택하고 두번째 plot은 right 를 선택한다.
plot width를 10으로 선택하면 그림의 가로가 길어지게 된다. 그림의 모양을 확인하고 download Multiplot버튼을 눌러서 그림을 다운로드 받으면 된다.