웹에서 하는 ggplot2

문 건 웅
10/14/2015

The Grammar of Graphics : 그래픽스 문법

  • Leland Wilkinson(2005)
  • Adjunctive Professor of Computer Science, University of Illinois at Chicago

ggplot2: 그래픽스문법에 따라 plot을 그리는 R 패키지

  • Hadley Wickham(2009)
  • Adjunctive Professor of Statistics at Rice University

R Graphics Cookbook: ggplot2 예제 및 설명서

  • Winston Chang(2012)
  • software engineer at RStudio

웹에서 클릭만으로 하는 R통계분석

  • 문건웅(2015)
  • Professor of Cardiology at Catholic University of Korea

대학교수의 근무 연수와 연봉

  • 데이타 : Salaries(2008-9)

plot of chunk unnamed-chunk-1

그래프의 구성

  1. 데이터(data):
    • ggplot에서는 R의 데이터프레임(data.frame)만 사용 가능하다.
  2. 좌표계(coordinate system):
    • 좌표계는 데이터가 투영되는 2차원 공간을 말하는 것으로, 예를 들어 Cartesian 좌표계(디폴트), polar 좌표계, map projection 등이 있다.
  3. 형태(geoms):
    • data를 나타내는 기하학적인 형태. 예를 들어 점(point), 선(line), 면(area), 다각형(ploygon) 등이 있다.
  4. 미적 특징(aesthetics) :
    • 데이터의 시각적 특징을 나타내는 것. 예를 들어 위치, 크기, 색, 투명도 등이 있다.
  5. 척도(scale):
    • 데이터의 미적 특징을 수치화하는 척도. 예를 들어 로그척도, 색척도, 크기척도 등이 있다.
  6. 통계(stats):
    • 데이터의 요약에 사용되는 통계학적인 변형. 예를 들어 개수, 평균, 중앙값, 회귀선 등이 있다.
  7. 분할(facets)
    • 데이터를 여러 개의 부분집합으로 나누고 작은 여러 개의 그래프로 분할하여 그리는 것을 말한다.

그래프를 그리는 순서

  1. 데이타 할당(data):
    • 데이타 프레임만 가능, 예: data=Salaries
  2. 변수 할당 또는 설정(aes)
    • x축 변수: 반드시 필요하다.
    • y축 변수: 경우에 따라 필요하다(히스토그램, 밀도 곡선 등은 x축 변수만 지정하여 그릴 수 있으며 산점도 등에는 x축 변수와 함께 y축 변수가 필요하다).
    • colour, fill, size 등에도 변수를 할당(예: colour = sex)하거나 설정(예: colour = “black”)할 수도 있다.
    • 영국식 철자 사용
  3. 형태 설정(geom):

    • 점(point), 선(line), 면(area), 다각형(ploygon) 등이 여러 형태를 layer by layer로 선택할 수 있다.
  4. 기타 :

    • 좌표계와 척도 등은 기본값이 있으므로 따로 변경할 필요가 있는 경우를 제외하고는 설정해주지 않아도 그래프를 그릴 수 있다.
    • 필요에 따라 좌표계/척도의 설정을 변경하거나
    • 통계를 추가하거나 면 분할 등을 추가할 수 있다.

ggplot2 로 만든 그래프의 예 : Salaries 데이타

require(ggplot2)    # ggplot()을 사용하기 위해
require(car)        # Salaries 데이터를 사용하기 위해

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 ...

데이타, 변수 할당

p <- ggplot(data=Salaries,                           # 데이타 할당
            aes(x=yrs.service,y=salary,colour=sex))  # 변수 할당
p
Error: No layers in plot

형태 설정 : blank

p <- ggplot(data=Salaries,                           # 데이타 할당 
            aes(x=yrs.service,y=salary,colour=sex))  # 변수 할당
p + geom_blank()                                     # 형태 없음

plot of chunk unnamed-chunk-4

점그래프 추가

p <- ggplot(data=Salaries,                           # 데이타 할당 
            aes(x=yrs.service,y=salary,colour=sex))  # 변수 할당
p + geom_point(size=4)                               # 점그래프 추가

plot of chunk unnamed-chunk-5

통계 추가 : loess 회귀선 추가

p <- ggplot(data=Salaries,                           # 데이타 할당 
            aes(x=yrs.service,y=salary,colour=sex))  # 변수 할당
p + geom_point(size=4) +                             # 점그래프 추가
    geom_smooth()                                    # 회귀선 추가

plot of chunk unnamed-chunk-6

면분할 : 성별로 면 분할

p <- ggplot(data=Salaries,                           # 데이타 할당 
            aes(x=yrs.service,y=salary,colour=sex))  # 변수 할당
p + geom_point(size=4) +                             # 점그래프 추가
    geom_smooth() +                                  # 회귀선 추가
    facet_grid(~sex)                                 # 면을 수직으로 분할 

plot of chunk unnamed-chunk-7

최종 결과

require(ggplot2)    # ggplot()을 사용하기 위해
require(car)        # Salaries 데이터를 사용하기 위해

p <- ggplot(data=Salaries,                                 # 데이타 할당 
            aes(x=yrs.service,y=salary,fill=sex))        # 변수 할당
p + geom_point(size=4,pch=21) +                            # 점그래프 추가
    geom_smooth(size=2,method="lm",formula=y~poly(x,2)) +  # 회귀선 추가
    ggtitle("대학교수의 연봉") + xlab("근무연수") + ylab("연봉($)")+
    theme_grey(base_family="NanumGothic")

plot of chunk unnamed-chunk-8

대학교수의 연봉 분포

require(ggplot2)    # ggplot()을 사용하기 위해
require(car)        # Salaries 데이터를 사용하기 위해

p <- ggplot(data=Salaries, aes(x=salary))     # 데이타,변수 할당
p + geom_density()                            # density 추가

plot of chunk unnamed-chunk-9

대학교수 직급별 연봉분포

require(ggplot2)    # ggplot()을 사용하기 위해
require(car)        # Salaries 데이터를 사용하기 위해

p <- ggplot(data=Salaries,aes(x=salary,fill=rank)) # 데이타, 변수 할당
p + geom_density()                                 # density 추가

plot of chunk unnamed-chunk-10

투명도 조절

require(ggplot2)    # ggplot()을 사용하기 위해
require(car)        # Salaries 데이터를 사용하기 위해

p <- ggplot(data=Salaries,aes(x=salary,fill=rank)) # 데이타, 변수 할당
p + geom_density(alpha=0.4)         # density 추가, 투명도 조절 

plot of chunk unnamed-chunk-11

Web-R.org

웹R의 방법: 데이타 선택

도전 1:

  • 데이타: diamonds plot of chunk unnamed-chunk-12
ggplot(data=diamonds[sample(nrow(diamonds),1000),],aes(x=carat,y=price,colour=cut))+ 
 geom_point()+ 
 ggtitle("Diamonds Are Forever")

plot of chunk unnamed-chunk-13

테마 적용

plot of chunk unnamed-chunk-14 plot of chunk unnamed-chunk-14 plot of chunk unnamed-chunk-14

점의 모양

plot of chunk unnamed-chunk-15

도전 2:

  • 데이타: singer plot of chunk unnamed-chunk-16
ggplot(data=lattice::singer,aes(x=height,fill=voice.part))+ 
 geom_density()+ 
 facet_grid(voice.part ~ .)+ 
 ggtitle("Singer's Height")

plot of chunk unnamed-chunk-17

도전 3: 영역그래프

  • 데이타: uspopage plot of chunk unnamed-chunk-18
ggplot(uspopage,aes(x=Year,y=Thousands,fill=AgeGroup))+ 
 geom_area(size=0.2,alpha=0.4) +
 geom_line(position='stack',size=0.2)+ 
 scale_fill_brewer(palette="Blues")+ 
 guides(fill=guide_legend(reverse=TRUE))

plot of chunk unnamed-chunk-19

팔레트 적용

plot of chunk unnamed-chunk-20 plot of chunk unnamed-chunk-20 plot of chunk unnamed-chunk-20

R의 표준 팔레트 보기

plot of chunk unnamed-chunk-21

taco 데이타

도전 4: 히트맵

  • 데이타 전처리하기: taco <- read.csv(“taco.results.csv”)
  • 사용할 데이타: taco

plot of chunk unnamed-chunk-22

taco=read.csv('taco_results.csv') 
ggplot(data=taco,aes(x=AgeGroup,y=Filling,fill=Rating))+ 
 geom_tile(colour='white')+ 
 scale_fill_gradientn(colours=c('white','steelblue'))+ 
 facet_grid(. ~ ShellType)+ 
 theme_bw()

plot of chunk unnamed-chunk-23

도전 5:박스플롯/바이올린플롯

plot of chunk unnamed-chunk-24

ggplot(data=Salaries,aes(x=rank,y=salary,fill=rank))+ 
 geom_violin(trim=FALSE)+ 
 geom_boxplot(fill='darkred',width=0.1)+ 
 stat_summary(geom='point',fun.y=mean,shape=23,size=3)+ 
 geom_point(position='jitter')+ 
 scale_fill_brewer(palette='Pastel2')+ 
 theme(legend.position='none')

plot of chunk unnamed-chunk-25

도전 6: polar plot

plot of chunk unnamed-chunk-26

도전 7: 산점도에 회귀식, 회귀결과표 넣기

require(gridExtra)

lm2table=function(mydata,xvar,yvar,parse=FALSE){
    fit=eval(parse(text=paste0("lm(",yvar,"~",xvar,",data=",mydata,")"))) 
    res1 = data.frame(summary(fit)$coeff)
    res2 = cbind(round(res1[,1:3],2),sprintf("%0.4f",res1[,4])) 
    colnames(res2) = c("Estimate", "Std. Error", "t value","Pr(>|t|)")
    res2
}

res=lm2table('mtcars','wt','mpg')
table_grob=tableGrob(res) 
ggplot(data=mtcars,aes(x=wt,y=mpg))+ 
 stat_smooth(method=lm)+ 
 geom_point()+ 
 annotate(geom='text',x=4,y=30,size=12,label='y = -5.3x + 37.3 (p < 0.001)',family='Times',fontface='italic')+ 
 annotation_custom(grob=table_grob,xmax=5,ymax=10)+ 
expand_limits(y=0)

도전 8: Multiplot