ggplot2로 막대그래프를 그렸는데 데이터가 양수와 음수로 구분이 되는 경우 그래프의 가독성을 높이기 위해서 양수냐, 음수냐에 따라 색상을 다르게 하고 싶을 때가 있습니다.

 

이번 포스팅에서는 R에 내장되어 있는 airquaility 데이터셋 (뉴욕의 1973년 5월~9월까지의 daily air quality measurements) 에서 5월달 온도(Temp) 만을 가져온 후에, 5월달 daily 온도의 1차 차분 데이터를 만들어서 막대그래프를 그려보도록 하겠습니다.

 

> str(airquality) 'data.frame': 153 obs. of 6 variables: $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ... $ Solar.R: int 190 118 149 313 NA NA 299 99 19 194 ... $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ... $ Temp : int 67 72 74 62 56 66 65 59 61 69 ... $ Month : int 5 5 5 5 5 5 5 5 5 5 ... $ Day : int 1 2 3 4 5 6 7 8 9 10 ... > sum(is.na(airquality$Temp)) [1] 0

>

> # 5월 온도만 선택
> May <- subset(airquality, select = c(Month, Day, Temp), subset = (Month == "5"))

>

 

 

온도의 1차 차분은 diff(변수, lag=차수) 함수를 사용합니다.  아래는 1차 차분을 하였으므로 5월1일은 빼고, 5월2일부터 5월31일까지의 날짜만 가져온 후에, 날짜와 온도 1차 차분한 값을 data frame으로 묶었습니다.  그 후에 ifelse() 함수를 사용해서 온도 1차 차분 값이 0 이상이면 "PLUS", 0 미만이면 "MINUS"라는 구분자 변수를 새로 생성하였습니다. 

 

> # 온도의 1차 차분
> May_Temp_Diff <- diff(May$Temp, lag=1)
> May_Temp_Diff
 [1]   5   2 -12  -6  10  -1  -6   2   8   5  -5  -3   2 -10   6   2  -9  11  -6  -3  14 -12   0  -4   1  -1  10  14  -2
[30]  -3
 
 

> # 5월2일 ~ 5월31일 날짜 변수 > May_Day <- May[c(2:31), c("Day")] > May_Day [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 >

 

> May_Temp_Diff.df <- data.frame(May_Day, May_Temp_Diff) > May_Temp_Diff.df May_Day May_Temp_Diff 1 2 5 2 3 2 3 4 -12 4 5 -6 5 6 10 6 7 -1 7 8 -6 8 9 2 9 10 8 10 11 5 11 12 -5 12 13 -3 13 14 2 14 15 -10 15 16 6 16 17 2 17 18 -9 18 19 11 19 20 -6 20 21 -3 21 22 14 22 23 -12 23 24 0 24 25 -4 25 26 1 26 27 -1 27 28 10 28 29 14 29 30 -2 30 31 -3 >

> # 온도 차분 plus, minus 여부 구분자 변수 생성

> attach(May_Temp_Diff.df) > May_Temp_Diff.df$plus_minus <- ifelse(May_Temp_Diff >= 0, "PLUS", "MINUS") > May_Temp_Diff.df May_Day May_Temp_Diff plus_minus 1 2 5 PLUS 2 3 2 PLUS 3 4 -12 MINUS 4 5 -6 MINUS 5 6 10 PLUS 6 7 -1 MINUS 7 8 -6 MINUS 8 9 2 PLUS 9 10 8 PLUS 10 11 5 PLUS 11 12 -5 MINUS 12 13 -3 MINUS 13 14 2 PLUS 14 15 -10 MINUS 15 16 6 PLUS 16 17 2 PLUS 17 18 -9 MINUS 18 19 11 PLUS 19 20 -6 MINUS 20 21 -3 MINUS 21 22 14 PLUS 22 23 -12 MINUS 23 24 0 PLUS 24 25 -4 MINUS 25 26 1 PLUS 26 27 -1 MINUS 27 28 10 PLUS 28 29 14 PLUS 29 30 -2 MINUS 30 31 -3 MINUS 

 
> detach(May_Temp_Diff.df)

 

 

ggplot2 패키지는 사용자가 추가로 설치해야 합니다.  intall.packages()함수로 설치하고 library() 함수로 호출해보겠습니다.

 

> install.packages("ggplot2")
> library(ggplot2) 

 

 

 

이제 준비가 다 되었습니다.  1차 차분한 5월달의 온도에 대해서 양수(전날 보다 온도 상승)는 빨간색, 음수(전날보다 온도 하락)는 파란색으로 막대 그래프를 그려보겠습니다.  aes(fill=구분자 변수) 함수를 사용하고, 색깔지정은 scale_fill_manual(values=c(색깔1, 색깔2)) 로 지정해주면 됩니다.

 

> # 양수는 빨간색, 음수는 파란색으로 막대 색 구분
> ggplot(data=May_Temp_Diff.df, aes(x=May_Day, y=May_Temp_Diff, fill=plus_minus)) + 
+   geom_bar(stat="identity", position="identity", colour="white", width=0.2) + # width 막대 폭 좁게
+   scale_fill_manual(values=c("blue", "red"), guide=FALSE) + # guide=F 범례 생략
+   ggtitle("1st order differenced Temp of May")

 

 

 

 

 

 

막대 폭이 너무 가늘어서 보기 싫다면, 막대 폭을 좀더 넓히고 싶다면 geom_bar(width=숫자) 함수를 사용하면 됩니다.

 

> # width 막대 폭 넓게
> ggplot(data=May_Temp_Diff.df, aes(x=May_Day, y=May_Temp_Diff, fill=plus_minus)) + 
+   geom_bar(stat="identity", position="identity", colour="white", width=1) + # width 막대 폭 넓게 
+   scale_fill_manual(values=c("blue", "red"), guide=FALSE) + # guide=F 범례 생략
+   ggtitle("1st order differenced Temp of May")

 

 

 

 

 

다음으로, 위의 그래프에서 보면 ggplot2 가 알아서 x축을 10, 20, 30으로 해서 10일 간격으로 설정해서 그래프를 그렸는데요, 이를 좀더 세분화하고 싶다면 scale_x_continuous(breaks=c(숫자, 숫자...)) 로 지정해주면 됩니다.

 

> # x축 세분화
> ggplot(data=May_Temp_Diff.df, aes(x=May_Day, y=May_Temp_Diff, fill=plus_minus)) + 
+   geom_bar(stat="identity", position="identity", colour="white", width=0.5) + 
+   scale_fill_manual(values=c("blue", "red"), guide=FALSE) + 
+   ggtitle("1st order differenced Temp of May") + 
+   scale_x_continuous(breaks=c(5, 10, 15, 20, 25, 30)) # x축 세분화

 

 

 

 

 

마지막으로, x축과 y축의 라벨 이름이 위에 보면 변수명이 그래도 들어가 있는데요, 좀더 이해하기 쉽도록 xlab(), ylab() 함수를 추가하여 x축, y축 라벨을 변경해보도록 하겠습니다.

 

> # modification of x label, y label
> ggplot(data=May_Temp_Diff.df, aes(x=May_Day, y=May_Temp_Diff, fill=plus_minus)) + 
+   geom_bar(stat="identity", position="identity", colour="white", width=0.5) + 
+   scale_fill_manual(values=c("blue", "red"), guide=FALSE) + 
+   ggtitle("1st order differenced Temp of May") + 
+   scale_x_continuous(breaks=c(5, 10, 15, 20, 25, 30)) + 
+   xlab("Day of May, 1973") + 
+   ylab("Temp difference from previous day")

 

 

 

 

많은 도움 되었기를 바랍니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

 

Posted by R Friend R_Friend

댓글을 달아 주세요

변수의 개수 및 데이터의 형태에 따라서 그래프, 시각화 방법이 달라지는데요,

 

지난번 포스팅에서는 일변량 연속형 데이터의 시각화 방법으로

 - 히스토그램(Histogram)
    : geom_histogram()

- 커널 밀도 곡선(Kernel Density Curve)
    : geom_density()

 - 박스 그래프(Box Plot)
    : geom_boxplot()

 - 바이올린 그래프(Violin Plot)
    : geom_violin()

에 대해서 알아보았습니다. 

 

 

이번 포스팅에서는 일변량 범주형 데이터의 시각화 방법으로서

 

 - 막대그림(Bar Chart): geom_bar()

 - 원그림(Pie Chart): geom_bar() + coord_polar()

 

에 대해서 소개해드리겠습니다.

 

 

[ 변수 개수 및 데이터 형태에 따른 그래프 ]

 

 

 

 

 

 

먼저, 범주별 도수를 구하고 이를 막대 형태로 나타낸 막대 그래프 (Bar Chart)를 ggplot2의 geom_bar() 로 그려보겠습니다. 

 

사용할 데이터는 MASS 패키지에 있는 Cars93 데이터 프레임에서 자동차 유형(Type), 제조국(Origin) 등의 범주형/요인(factor)형 변수를 사용하겠습니다.

 

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

 

 

자동차 유형(Type)별 도수를 가지고 막대그림을 그려보겠습니다.

 

> ggplot(Cars93, aes(x=Type)) + 
+   geom_bar(fill="white", colour="black") + 
+   ggtitle("Bar Chart of Frequency by Car Type")

 

 

 

 

 

 

위와 똑같은 그래프를 그려볼건데요, 이번에는 aes(x, y)의 x변수와 도수에 해당하는 y변수로 된 데이터프레임을 만들어서 이를 직접 x, y에 입력해서 그래프를 그려보겠습니다 (간편하게는 위의 방식 사용하면 되구요, 아래 처럼 데이터가 구성이 되어있다면 이번 방식을 이용하면 되겠습니다).  아래 예제에서는 자동차 유형(Type)별로 도수를 집계(aggregation)할 때 sqldf 패키지를 사용하였습니다.

 

> install.packages("sqldf")
> library(sqldf)
> 
> Car_Type_cnt <- sqldf( 'select Type, count(*) as Type_cnt
+                           from Cars93
+                           group by Type
+                           order by Type
+                         ')
> 
> Car_Type_cnt
     Type Type_cnt
1 Compact       16
2   Large       11
3 Midsize       22
4   Small       21
5  Sporty       14
6     Van        9
> 
> sapply(Car_Type_cnt, class)
     Type  Type_cnt 
 "factor" "integer" 

 

다음으로 자동차 유형(Type)별로 geom_bar()를 이용하여 막대그림을 그려보도록 하겠습니다.  y에 직접 입력해주고, geom_bar()에 stat="identity"를 설정해주어야 합니다.

 

> # 자동차 유형별 도수 막대 그림
> library(ggplot2)
> 
> ggplot(Car_Type_cnt, aes(x=Type, y=Type_cnt)) + 
+   geom_bar(stat="identity", fill="white", colour="black") + 
+   ggtitle("Bar Chart of Frequency by Car Type")

 

 

 

 

 

 


 

일변량에 더해서, 이번에는 2개의 변수를 사용한 막대그림도 살펴보도록 하겠습니다.  차종(Type) 별 제조국(Origin) 별 자동차 수를 가지고 막대그림을 그려보도록 하겠습니다. 

 

> # Origin별 구분 추가하기
> ggplot(Cars93, aes(x=Type, fill=Origin)) + 
+   geom_bar(position="dodge", colour="black") + 
+   scale_fill_brewer(palette=1) +
+   ggtitle("Bar Chart of Frequency by Car Type & Origin")

 

 

 

 

 

 

이번에는 위와 동일한 그래프를 그릴건데요, sqldf()로 차종(Type)별 & Origin 별 자동차 도수를 집계를 해서 데이터프레임을 만들어서 막대그림을 그려보겠습니다.

 

> # 차종(Type) 별 실린더개수(Cylinders) 별 자동차 개수 > library(sqldf)

> Car_Type_Origin_cnt <- sqldf( 'select Type, Origin, count(*) as Type_Origin_cnt + from Cars93 + group by Type, Origin + order by Type, Origin + ') > Car_Type_Origin_cnt Type Origin Type_Origin_cnt 1 Compact USA 7 2 Compact non-USA 9 3 Large USA 11 4 Midsize USA 10 5 Midsize non-USA 12 6 Small USA 7 7 Small non-USA 14 8 Sporty USA 8 9 Sporty non-USA 6 10 Van USA 5 11 Van non-USA 4 >

 

geom_bar()로 막대그림을 그리되, 처음의 일변량 때와는 다르게 fill=Origin 로 하여서 제조국별로 구분을 해보겠습니다.  position="dodge" 를 하면 수평으로 나란히 Origin별로 그려집니다.

 

> ggplot(Car_Type_Origin_cnt, aes(x=Type, y=Type_Origin_cnt, fill=Origin)) + 
+      geom_bar(stat="identity", position="dodge", colour="black") + 
+      scale_fill_brewer(palette=1) +
+      ggtitle("Bar Chart of Frequency by Car Type & Origin_1")

 

 

 

 

 

만약 position="dodge" 옵션을 지정하지 않으면 아래와 같이 세로로 올라탄 그래프 형식으로 제시됩니다.

 

> # without position="dodge" > ggplot(Car_Type_Origin_cnt, aes(x=Type, y=Type_Origin_cnt, fill=Origin)) + + geom_bar(stat="identity", colour="black") + # position="dodge" 미지정 + scale_fill_brewer(palette=1) + + ggtitle("Bar Chart of Frequency by Car Type & Origin, without podge option")

 

 

 

많은 도움이 되었기를 바랍니다.

다음번 포스팅에서는 원그림(Pie Chart)를 알아보겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 고양이 발바닥 2016.11.15 11:52  댓글주소  수정/삭제  댓글쓰기

    안녕하세요!
    R 포스팅에서 많이 배우고 있습니다.

    중간에 차종(Type) 별 제조국(Origin) 별 자동차 수를 가지고 막대그림을 그리는 내용 이후부터
    중간중간 내용이 비거나 건너뛰는 느낌이 있는 것 같아서 글 남깁니다!

    올려주신글 항상 유익하게 읽고 있습니다.
    감사드려요!

    • R Friend R_Friend 2016.11.17 00:15 신고  댓글주소  수정/삭제

      안녕하세요 고양이 발바닥님,

      댓글 감사합니다.

      제가 한번 글을 써놓고, 중간에 좀 쉬다가 후반부 update 하면서 input dataset이랑 ggplot2 함수를 서로 맞추어야 했는데 그만 수정을 안했었네요.

      댓글 남겨주셔서 감사합니다. 덕분에 수정했네요. ^^