이전 포스팅에서 하나의 그래프에 텍스트, 선, 화살표, 음영있는 사각형 등으로 부연 설명을 추가하기 위해 annotate() 함수로 주석을 추가하는 방법을 소개하였습니다. 

 

이번에는 facet_grid() 로 특정 범주형 변수에 의해 요인(factor)별로 면 분할된 그래프에 각각 주석을 넣는 넣기 위해 geom_text() 함수를 사용하는 방법에 대해 알아보겠습니다.

 

 

예제로 사용할 데이터는 iris 데이터프레임 내 Petal.Width, Petal.Length, Species 의 3개 변수를 사용하겠습니다.

 

 
> str(iris)
'data.frame':	150 obs. of  5 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
 

 

 

 

ggplot2는 별도의 설치 및 호출이 필요한 패키지이므로 아래의 절차를 먼저 따르기 바랍니다.

 

 
> install.packages("ggplot2")
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/ggplot2_1.0.1.zip'
Content type 'application/zip' length 2676992 bytes (2.6 MB)
downloaded 2.6 MB

package ‘ggplot2’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
	C:\Users\user\AppData\Local\Temp\Rtmp0CW98B\downloaded_packages
> library(ggplot2)
 

 

 

 

먼저, 지난번 포스팅에서 소개드렸던, 하나의 화면에 품종별로 색깔을 구분해서 그리고, annotate() 함수를 사용해서 텍스트 주석(text annotation) 하는 방법을 아래에 복습해 보겠습니다.

 

 

> # 하나의 화면에 품종별로 색깔 구분해서 그리기 : aes(fill=categorical var)
> a1 <- ggplot(iris, aes(x=Petal.Width, y=Petal.Length, fill=Species)) + 
+   geom_point(colour="grey", shape=21, size=6) +
+   scale_fill_brewer(palette="Reds") + 
+   annotate("text", x=0.25, y=2.4, label="Setosa", size=7) + # text annotation
+   annotate("text", x=1.3, y=3.3, label="Versicolor", size=7) + 
+   annotate("text", x=1.7, y=6.8, label="Virginica", size=7)
> 
> a1

 

 

 

 

 

 


 

 

이걸 품종(Species)을 기준으로 면 분할 (facet_grid(.~Species) ) 하면 아래와 같습니다.  이번 포스팅에서는 아래 처럼 면 분할 된 상태의 그래프에 주석 추가하는 방법입니다.

 

 
> # 품종별로 면 분할하여 색깔 구분없이 그리기 : facet_grid(.~categorical var)
> g1 <- ggplot(iris, aes(x=Petal.Width, y=Petal.Length)) + 
+   geom_point(colour="blue", shape=19, size=4) +
+   facet_grid(.~Species)
> 
> g1

 

 

 

 

 

 

범주형 변수의 요인(factor)별로 면 분할된 상태의 그래프에 텍스트 주석을 넣으려고 아래와 같이 하면 라벨 길이가 다르다면서 에러가 납니다.

 

 
> # 텍스트 라벨 넣으려면 에러 발생 
> # Error: Incompatible lengths for set aesthetics: label
> g1 + 
+   annotate("text", x=1, y=7, label=c("Setosa", "Versicolor", "Virginica"))
Error: Incompatible lengths for set aesthetics: label

 

 

 

 

범주형 변수의 요인(factor)별로 면 분할된 상태의 그래프에 텍스트 주석을 넣으려고 하려면 annotate() 함수로는 안되구요, 라벨을 넣으려는 내용을 데이터프레임으로 미리 만들어놓고 geom_text()로 라벨을 집어넣어야 합니다. 아래 예제는 Species 이름을 각 각 텍스트로 넣어보는 예입니다.

 

 

> # 분할 면마다 각각 텍스트 주석 넣기 : geom_text()

> # dataframe of label
> iris_species_labels <- data.frame(Species = c("setosa", "versicolor", "virginica"), 
+                        label = c("Species=Setosa", "Species=Versicolor", "Species=Virginica"))
> 
> g2 <- g1 + 
+   geom_text(x=1, y=6.5, aes(label=label), data=iris_species_labels)
>   
> g2

 

 

 

 

 

 

 


 

 

다음으로 각 품종(Species)별로 x축 Petal.Width와 y축 Petal.Length 평균을 구해서 중심 좌표 (centroid)를 텍스트로 주석을 추가해보겠습니다.

 

먼저, sqldf 패키지를 새로 설치해서 x축 Petal.Width와 y축 Petal.Length 평균을 구해보겠습니다.

 

 

> install.packages("sqldf") > library(sqldf) > > mean_iris <- sqldf('select "Species", + avg("Petal.Width") as "mean_Petal.Width", + avg("Petal.Length") as "mean_Petal.Length" + from iris + group by Species + order by Species + ') > > mean_iris Species mean_Petal.Width mean_Petal.Length 1 setosa 0.246 1.462 2 versicolor 1.326 4.260 3 virginica 2.026 5.552 

 

> label_mean_iris <- transform(mean_iris, 
+                              centroid=paste(c("centroid("), 
+                                             round(mean_Petal.Width, 2), 
+                                             c(", "), 
+                                             round(mean_Petal.Length, 2), 
+                                             c(")"), 
+                                             sep=""))
> 
> label_mean_iris
     Species mean_Petal.Width mean_Petal.Length             centroid
1     setosa            0.246             1.462 centroid(0.25, 1.46)
2 versicolor            1.326             4.260 centroid(1.33, 4.26)
3  virginica            2.026             5.552 centroid(2.03, 5.55)
 

 

 

 

다음으로 centroid 정보를 그래프에 분할된 면에 따라 각각 추가해보겠습니다.

 

 
> # x, y 평균 좌표 추가 : geom_text()
> g3 <- g2 +
+   geom_text(x=1, y=6, aes(label=centroid), data=label_mean_iris)
> 
> g3

 

 

 

 

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

 

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

 

 

Posted by R Friend R_Friend

댓글을 달아 주세요

그동안 R로 다양한 그래프를 그리는 방법을 알아보았습니다.  R로 그래프를 그렸다면, 보는 이의 가독성, 해석의 용이성을 높여주기 위해서 그래프 위에 텍스트, 가로선/세로선/대각선, 화살표, 음영 사각형, 제목 등과 같이 추가로 정보를 제공하거나 강조를 하고 싶은 부분에 주석을 달고 싶을 때가 있습니다.

 

 

- 텍스트 : annotate("text")

 

- 가로선/세로선/대각선 : geom_vline(), geom_hline(), geom_abline()

 

- 화살표 : annotate("segment", arrow=arrow()) , with grid package


- 음영 사각형 : annotate("rect")


- 제목 : ggtitle()

 

 

매번의 R 그래프/시각화 포스팅마다 주석 다는 방법을 간간이 곁들여서 소개해드리기는 했는데요, 이번 포스팅에서는 주석 다는 방법에 대해서 포괄적이고 종합적으로 정리를 해서 바로 찾아보기 편하도록 정리를 해보았습니다.

 

 

예제로 사용할 데이터는 Base Package에 내장되어 있는 iris 데이터 프레임의 Petal.Width, Petal.Length, Species 의 세개 변수를 사용하겠습니다. (iris 데이터셋은 데이터 마이닝 실습에 아주 많이 사용되는 데이터셋으로서, iris 꽃 품종 중 setosa 50개, versicolor 50개, virginica 50개를 꽃잎의 넓이와 길이를 측정해놓은 데이터셋입니다)

 

 

 

> str(iris)
'data.frame':	150 obs. of  5 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ... 

 

 

ggplot2는 별도의 설치 및 호출이 필요한 패키지이므로 아래의 절차를 먼저 실행하시기 바랍니다.

 

> install.packages("ggplot2")
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/ggplot2_1.0.1.zip'
Content type 'application/zip' length 2676992 bytes (2.6 MB)
downloaded 2.6 MB

package ‘ggplot2’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
	C:\Users\user\AppData\Local\Temp\RtmpEfAwCj\downloaded_packages
> library(ggplot2) 

 

(1) iris의 Petal.Width를 x축으로, Petal.Length를 y축으로 하고, 품종(Species)에 따라서 색깔을 달리해서 산포도(scatter plot)을 그려보겠습니다.

 

> # scatter plot of iris dataset
> a1 <- ggplot(iris, aes(x=Petal.Width, y=Petal.Length, fill=Species)) + 
+   geom_point(colour="grey", shape=21, size=6) +
+   scale_fill_brewer(palette="Reds")
> 
> a1
 

 

 

 

 

(2) 텍스트(text) 추가 : annotate("text")

 

> # 텍스트(text) 추가 : annotate("text")
> 
> a2 <- a1 + 
+   annotate("text", x=0.25, y=2.4, label="Setosa", size=7) + # text annotation
+   annotate("text", x=1.3, y=3.3, label="Versicolor", size=7) + 
+   annotate("text", x=1.7, y=6.8, label="Virginica", size=7)
> 
> a2

 

 

 

 

 

 

(3) 선(line) 추가 : geom_vline(), geom_hline(), geom_abline()

 

> # 선(line) 추가 : geom_vline(), geom_hline(), geom_abline()
> 
> a3 <- a2 + 
+   geom_hline(yintercept=2.6, colour="grey", lty="dashed", size=1) + # horizontal line
+   geom_hline(yintercept=4.9, colour="grey", lty="dashed", size=1) + 
+ 
+   geom_vline(xintercept=0.8, colour="grey", lty="dashed", size=1) + # vertical line
+   geom_vline(xintercept=1.75, colour="grey", lty="dashed", size=1) + 
+   
+   geom_abline(intercept=8, slope=-2.1, colour="red", lty="dotted", size=1.5) # abline
>   
> a3

 

 

 

 

 

(4) 화살표(arrow) 추가 : annotate("segment")

 

단, grid 패키지를 호출해서 사용해야 합니다.

 

> # 화살표(arrow) 추가 : annotate("segment")
> library(grid) # grid 패키지 호출
> 
> a4 <- a3 + 
+   annotate("segment", x=2, xend=2.1, y=2, yend=3.5, size=1.5, colour="red", arrow=arrow())
> 
> a4
> 
> 
> # 텍스트 추가 : annotate("text")
> a5 <- a4 + 
+   annotate("text", x=2, y=1.8, size=6, colour="red", label="y=8 - 2.1x")
> 
> a5

 

 

 

 

 

 

 

(5) 음영 사각형(shadowed box) 추가 : annotate("rect")

 

> # 음영 사각형(shadowed box) 추가 : annotate("rect")
> a6 <- a5 + 
+   annotate("rect", xmin=0, xmax=0.8, ymin=0, ymax=2.6, alpha=0.1, fill="red") + 
+   annotate("rect", xmin=0.8, xmax=1.75, ymin=2.6, ymax=4.9, alpha=0.2, fill="red") + 
+   annotate("rect", xmin=1.3, xmax=2.7, ymin=4.3, ymax=7.2, alpha=0.3, fill="red")
> 
> a6

 

 

 

 

 

(6) 제목(title) 추가 : ggtitle()

 

> # 제목 추가 : ggtitle()
> 
> a7 <- a6 + 
+   ggtitle("Annotation of Text, Line, Arrow, Shadowed Box, Title")
> 
> a7

 

 

 

 

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

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

이번 포스팅에서는 R ggplot2에서 그래프 색깔 설정 (colour setting), 조절하는 방법에 대해서 알아보겠습니다.  이전의 각 그래프 종류별로 소개한 내용에도 색깔 지정에 대한 내용이 조금씩 포함되어 있기는 합니다만, 이번 포스팅에서는 색깔 설정에 대한 경우의 수를 종합적으로 포괄해서 정리를 해보았습니다.

 

그래프에서 색깔을 특정 변수의 변화와 align하게 되면 x축과 y축의 2차원에 색깔이라는 차원을 추가함으로써 3차원의 정보를 제공할 수 있습니다.  회사 업무 보고서에 엑셀로 그린 그래프를 많이 사용하고는 하는데요, x축과 y축의 2차원을 넘어서는, 특정 조건에 따라서 색깔이나 모양을 달리해야 하는 경우라면 엑셀로 그래프를 그리는 것이 거의 불가능하게 됩니다.  이때 R이 데이터 전처리/변환부터 해서 인쇄용으로 바로 사용해도 좋을 만큼의 고품질의 그래프를 그리는데 아주 특출난 역할을 할 수 있습니다.  R 그래프에서 색깔을 자유자재로 사용할 수 있다면 미적으로도 보기에 좋겠지요?!

 

 

이번 예제에서 사용할 데이터는 MASS 패키지에 내장되어 있는 Cars93 데이터 프레임의 차 무게(Weight)와 고속도로연비(MPG.highway), 차 가(Price), 실린더 개수(Cylinders)의 4개 변수를 사용하겠습니다.

 

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

 

ggplot2 패키지는 별도의 설치 및 호출이 필요하므로 아래의 절차를 먼저 시행합니다.

 

> install.packages("ggplot2") # 설치

> library(ggplot2)  

 

 

색상 변화를 잘 살펴볼 수 있도록 속이 빈 동그라미 모양인 shape=21 번의 도형을 사용해서 size=6 으로 큼지막하게 키워서 예를 들어보겠습니다. 

 

 

(1) 색깔 설정을 별도로 하지 않은 경우 디폴트 테두리 검정색 (default colour)

 

> # default colour
> ggplot(Cars93, aes(x=Weight, y=MPG.highway)) +
+   geom_point(shape=21, size=6)

 

 

 

 

 

(2) 테두리 선 색깔 지정 (colour : line colour setting)

 

> # 테두리 선 색깔 지정 (colour : line colour setting)
> ggplot(Cars93, aes(x=Weight, y=MPG.highway)) +
+   geom_point(shape=21, size=6, colour="blue")

 

 

 

 

 

 

(3) 도형의 속 채우기 색깔 지정 (fill : innner colour fill-up)

 

> # 도형의 속 채우기 색깔 (fill : inner colour fill-up)
> ggplot(Cars93, aes(x=Weight, y=MPG.highway)) +
+   geom_point(shape=21, size=6, fill="blue")

 

 

 

 

 

 

(4) 연속형 변수의 숫자에 따른 색깔 조절 : aes(fill=continuous variable)

 

> # 연속형 변수의 숫자에 따른 색깔 조절
> # (fill : colour change aligned with continuous numeric variable)
> ggplot(Cars93, aes(x=Weight, y=MPG.highway, fill=Price)) +
+   geom_point(colour="grey", shape=21, size=6)

 

 

 

 

 

 

(5) 범주형 변수의 범주/요인(factor)에 따른 색깔 조절 : aes(fill=categorical variable)

 

> # 범주형 변수의 범주/요인(factor) 따른 색깔 조절 
> # (fill : colour change aligned with categorical variable)
> ggplot(Cars93, aes(x=Weight, y=MPG.highway, fill=Cylinders)) +
+   geom_point(colour="grey", shape=21, size=6)

 

 

 

 

 

###  아래의 palette 설정은 범주형 데이터 (categorical data)에만 해당됩니다.  

 

(6) Palette = Oranges 색 설정 (pallet colour setting) : scale_fill_brewer()

 

> # Palette = Oranges 색 설정 (palette colour setting) : scale_fill_brewer()
> ggplot(Cars93, aes(x=Weight, y=MPG.highway, fill=Cylinders)) +
+   geom_point(colour="grey", shape=21, size=6) +
+   scale_fill_brewer(palette="Oranges") # Oranges

 

 

 

 

 

 

(7) Palette = Reds 색 설정 (pallet colour setting) : scale_fill_brewer()

 

> # Palette = Reds 색 설정 (palette colour setting) : scale_fill_brewer()
> ggplot(Cars93, aes(x=Weight, y=MPG.highway, fill=Cylinders)) +
+   geom_point(colour="grey", shape=21, size=6) +
+   scale_fill_brewer(palette="Reds") # Reds

 

 

 

 

 

(8) Palette = Blues 색 설정 (pallet colour setting) : scale_fill_brewer()

 

> # Palette = Blues 색 설정 (palette colour setting) : scale_fill_brewer()
> ggplot(Cars93, aes(x=Weight, y=MPG.highway, fill=Cylinders)) +
+   geom_point(colour="grey", shape=21, size=6) +
+   scale_fill_brewer(palette="Blues") # Blues

 

 

 

 

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

 

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

 

 

Posted by R Friend R_Friend

댓글을 달아 주세요

ggplot2 그래프를 그렸을 때 x축이나 y축의 디폴트 값을 사용해도 무리가 없는 경우가 많기는 합니다만, 

 

분석가가 x축이나 y축을 좀더 사용하는 목적에 맞게 설정을 조정하고 싶을 때가 있습니다. 

 

이때 사용할 수 있는 ggplot2의 함수 3가지를 알아보도록 하겠습니다. 

 

(1) 1:1 의 비율로 x축과 y축 설정

 : coord_fixed()

 

(2) 일정한 간격으로 x축, y축 설정

 : scale_x_continuous(breaks=seq())

 

(3) 분석가 마음대로 x축, y축 설정

 : scale_x_continuous(breaks=c())

 

 

예제로 사용할 데이터는 MASS 패키지에 내장되어 있는 Cars93 데이터 프레임의 도시연비(MPG.city), 고속도로연비(MPG.highway)가 되겠습니다.  scale이 연비로서 서로 같은 변수를 선택하였으며, 산점도를 그려보면서 x축, y축 설정을 바꿔보도록 하겠습니다.

 

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

 

 

 

ggplot2는 신규 설치 및 호출이 필요한 패키지이므로 아래와 같은 사전 절차가 필요합니다.

 

> # ggplot2 설치 및 호출

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

 

순서대로 하나씩 살펴보겠습니다.  함수 옵션을 바꿔줌에 따라서 x축, y축 결과가 어떻게 바뀌는지 살펴보시고, 필요로 하는 함수 옵션을 선택해서 사용하시면 되겠습니다.

 

(0) Default setting

 

> # default setting of x and y axis
> ggplot(Cars93, aes(x=MPG.city, y=MPG.highway)) +
+   geom_point(shape=21, colour="black", size=3) + 
+   ggtitle("default setting of x and y axis") 
 

 

 

 

 

(1) 1:1 의 비율로 x축과 y축 설정 : coord_fixed()

 

> # 1:1 proportion of x and y axis : coord_fixed()
> ggplot(Cars93, aes(x=MPG.city, y=MPG.highway)) +
+   geom_point(shape=21, colour="black", size=3) + 
+   coord_fixed() +
+   ggtitle("1:1 proportion of x and y axis : coord_fixed()")

 

 

 

 

 

 

(2) 일정한 간격으로 x축과 y축 설정 : scale_x_continuous(breaks=seq())

 

> # manual setting with fixed interval of x and y axis : scale_x_continuous(breaks=seq())
> ggplot(Cars93, aes(x=MPG.city, y=MPG.highway)) +
+   geom_point(shape=21, colour="black", size=3) + 
+   coord_fixed() +
+   scale_x_continuous(breaks=seq(0, 80, 5)) + 
+   scale_y_continuous(breaks=seq(0, 80, 5)) + 
+   ggtitle("manual setting with fixed interval of x and y axis : scale_x_continuous(breaks=seq())")

 

 

 

 

 

 

 

(3) 분석가 마음대로 x축과 y축 설정 : scale_x_continuous(breaks=c())

 

> # manual setting of x and y axis : scale_x_continuous(breaks=c())
> ggplot(Cars93, aes(x=MPG.city, y=MPG.highway)) +
+   geom_point(shape=21, colour="black", size=3) + 
+   coord_fixed() +
+   scale_x_continuous(breaks=c(10, 15, 20, 25, 30, 40)) + 
+   scale_y_continuous(breaks=c(20, 25, 30, 40, 50)) + 
+   ggtitle("manual setting of x and y axis : scale_x_continuous(breaks=c())")

 

 

 

 

함수 옵션을 바꿔줌에 따라서 x축, y축 결과가 어떻게 바뀌는지 살펴보시고, 필요로 하는 함수 옵션을 선택해서 사용하시면 되겠습니다.

 

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

 

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 2018.09.13 18:27  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  2. R Friend R_Friend 2018.09.13 18:47 신고  댓글주소  수정/삭제  댓글쓰기

    (1) 데이터셋을 하나의 데이터프레임으로 합친 후에
    (이때 40개 파일을 구분할 수 있는 요인형(factor) 칼럼이 있어야 함)

    (2) ggplot2의 gacet_grid() 함수를 이용하면 될거 같습니다.
    (참고: rfriend.tistory.com/85 )

  3. 2018.12.26 09:58  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • R Friend R_Friend 2018.12.26 13:35 신고  댓글주소  수정/삭제

      안녕하세요 hmmoon 님, url 남겨주신 곳에 가서 확인해보니 산점도인데 그룹에 따라서 색깔을 달리하는 그래프를 원하시는 것 같습니다.

      http://rfriend.tistory.com/72
      포스팅에 가셔서

      > # Scatter Plot by Type, using different Colours
      > ggplot(data=Cars93, aes(x=Weight, y=MPG.highway, colour=Type)) +
      + geom_point(shape=19, size=3) +
      + ggtitle("Scatter Plot by Type, using different Colours")

      코드를 참고하시면 될 듯 합니다.
      해보시고 잘 안되면 다시 한번 댓글 남겨주시구요.

      감사합니다.

그룹(집단, 요인) 간의 데이터 분포 형태, 변화 추이 등을 비교 분석하기에 유용한 방법으로 비교하려는 축을 기준으로 면을 분할하여 그래프를 그룹 간 비교하는 방법이 있습니다.

 

Lattice 패키지에서는 Trellis 를 사용하는데요, ggplot2 패키지에서는 facet_grid() 함수facet_wrap() 함수를 사용하여 면 분할을 구현할 수 있습니다.

 

Base Graphics 패키지에서는 par() 함수를 사용해서 면 분할을 지정해줄 수 있습니다만, x축과 y축의 scale이 들쭉날쭉해서 직접적으로 서로 비교하기가 곤란하거나, y축의 min, max 값이 그룹 간 숫자를 모두 감안해서 자동 설정되는 것이 아니다보니 분석가가 미리 y축 값의 범위를 계산해보고, 혹은 그려보고 나서 y축 값을 세팅해줘야 하므로 lattice나 ggplot2 대비 불편합니다.  따라서 집단간 비교를 위한 면 분할이 필요한 경우 ggplot2나 lattice 패키지를 권합니다.

 

MASS 패키지 내 무게(Weight), 고속도로연비(MPG.highway), 차종(Type, 범주형), 생산국가(Origin, 범주형) 의 4개 변수를 사용해서, x축에 무게(Weight), y축에 고속도로연비(MPG.highway), 그리고 면 분할의 기준으로 범주형 변수인 차종(Type)과 생산국가(Origin) 변수를 사용하겠습니다.

 

facet_grid()를 먼저 예제를 보이고, 그 후에 facet_wrap()의 예제를 들겠습니다.  두 함수가 비슷하면서도 조금 다릅니다.  분석가가 필요로 하는 아웃풋 이미지에 맞게 골라서 사용하면 되겠습니다.

 

 

(1) facet_grid()

 

> # facet_grid()
> ggplot(Cars93, aes(x=Weight, y=MPG.highway)) +
+   geom_point(shape=21, colour="black") +
+   facet_grid(Type ~ .)
 

 


 

> ggplot(Cars93, aes(x=Weight, y=MPG.highway)) +
+   geom_point(shape=21, colour="black") +
+   facet_grid(. ~ Type)

 

 

 

 


 

> ggplot(Cars93, aes(x=Weight, y=MPG.highway)) +
+   geom_point(shape=21, colour="black") +
+   facet_grid(Origin ~ Type)

 

 

 

 

 

 

 

(2) facet_wrap()

 

facet_wrap()는 ncol 또는 nrow 로 행 또는 열의 개수를 분석가가 지정할 수 있어서 좋은 점이 있습니다.

 

> # facet_wrap()
> ggplot(Cars93, aes(x=Weight, y=MPG.highway)) +
+   geom_point(shape=21, colour="black") +
+   facet_wrap( ~ Type, ncol=3)

 

 

 


 

> ggplot(Cars93, aes(x=Weight, y=MPG.highway)) +
+   geom_point(shape=21, colour="black") +
+   facet_wrap(Origin ~ Type, ncol=3)

 

 

 


 

> ggplot(Cars93, aes(x=Weight, y=MPG.highway)) +
+   geom_point(shape=21, colour="black") +
+   facet_wrap(Origin ~ Type, ncol=2)

 

 

 

 

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

 

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

 

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 로리너 2017.08.11 16:07 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 포스팅 잘 보고 있습니다.
    질문드릴 것이 하나 있어서 댓글 남겨봅니다..

    몇 가지 요인에 의하여 변동하는 결과값 평균을 비교하기 위해 이러한 모양새로 그래프를 그리고 싶은데요, 이 포스팅과 같은 패키지, 기능을 이용할 수 있나요?

    예를 들어 온도와 산성도, 지속시간을 달리하여 얻어낸 결과값들이 셋 중 어떤 요인에 의하여 더 크게 변화하는지를 시각화하고 싶습니다

    따라해보려 했는데 x축 설정에 애를 먹더군요

    • R Friend R_Friend 2017.08.11 17:43 신고  댓글주소  수정/삭제

      안녕하세요, 로리러님.

      풀려고하는 문제가 정확히 무엇인지 몰라서 답변드리기가 좀 애매한데요, 혹시 이원분산분석으로 풀수 있는 문제이면 아래 포스팅 참고하시기 바랍니다. 중간에 그래프도 포함되어 있습니다.

      http://rfriend.tistory.com/136
      ----------------------------------------------

      그리고 다변량 시각화 하는 필요가 있으시면 블로그의 [다변량 시각화] 구분이 제목에 붙어있는 포스팅도 참고해보시면 좋겠습니다.

      가령, (각 변수 sacle 표준화 후)
      - 평행좌표그림
      - 클리브랜드 점 그래프
      - 3D 산점도

      등을 고려해볼 수 있을거 같습니다.

      -----------------------------------------------

      여러개 변수들의 성대적 (Y값에 대한) 중요도를 시각화 하려면 Random Forest 의 "Feature(Variable) Importance" 도 대안이 될 수있을거 같습니다

  2. 로리너 2017.08.11 17:47 신고  댓글주소  수정/삭제  댓글쓰기

    답변 감사드립니다.

    역시 전달이 힘드네요 ㅎㅎ;

    말씀하신 부분 충분히 알아보겠습니다. 좋은 주말 되십시오

이전 포스팅에서 x축과 y축의 값에 따라 산점도 그리는 방법을 알아보았다면, 이번 포스팅에서는 여기에 더해서 z라는 제 3의 변수에 비례해서 점의 크기를 변화시켜서 그린 그래프가 버블 그래프 (Bubble Chart) 입니다.  산점도가 2차원의 그래프(단, 색깔이나 모양 조건을 추가하면 3차원 정보 제공 가능)라면, 버블 그래프 (Bubble Chart)는 3차원의 그래프가 되어 지면에 보다 많은 정보량을 제공할 수 있는 장점이 있습니다. 

 

ggplot2에서는 산점도, 점 그래프를 그리는 geom_point() 함수와 함께 scale_size_area() 함수를 같이 사용하면 버블 그래프 (Bubble Chart)를 그릴 수가 있습니다.

 

MASS 패키지의 Cars93 데이터 프레임 내에 차 모델명(Model), 차종(Type), 무게(Weight), 고속도로연비(MPG.highway), 가격(Price)의 5개 변수를 사용하여 버블 그래프를 그려보겠습니다.  데이터가 너무 많으면 버블 그래프를 그릴 때 겹쳐 보여서 보기 싫으므로 차종(Type)에서 "compact"와 "large"의 두 종만 선별해서 예를 들어보겠습니다.

 

> 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 ...
 
> levels(Cars93$Type)
[1] "Compact" "Large"   "Midsize" "Small"   "Sporty"  "Van" 
 
 

> table(Cars93$Type) Compact Large Midsize Small Sporty Van 16 11 22 21 14 9

 

 

> # dataset selection

> Cars93_sample <- subset(Cars93, 
+                         select = c("Model", "Type", "Weight", "MPG.highway", "Price"), 
+                         subset = (Type %in% c("Compact", "Large")))
> Cars93_sample
            Model    Type Weight MPG.highway Price
3              90 Compact   3375          26  29.1
7         LeSabre   Large   3470          28  20.8
8      Roadmaster   Large   4105          25  23.7
10        DeVille   Large   3620          25  34.7
12       Cavalier Compact   2490          36  13.4
13        Corsica Compact   2785          34  11.4
18        Caprice   Large   3910          26  18.8
20       Concorde   Large   3515          28  18.4
21        LeBaron Compact   3085          28  15.8
22       Imperial   Large   3570          26  29.5
25         Spirit Compact   2970          27  13.3
30         Vision   Large   3490          28  19.3
33          Tempo Compact   2690          27  11.3
38 Crown_Victoria   Large   3950          26  20.9
43         Accord Compact   3040          31  17.5
52       Town_Car   Large   4055          26  36.1
55            626 Compact   2970          34  16.5
58           190E Compact   2920          29  31.9
65         Altima Compact   3050          30  15.7
68        Achieva Compact   2910          31  13.5
71   Eighty-Eight   Large   3470          28  20.7
74        Sunbird Compact   2575          31  11.1
77     Bonneville   Large   3495          28  24.4
78            900 Compact   2775          26  28.7
82         Legacy Compact   3085          30  19.5
90         Passat Compact   2985          30  20.0
92            240 Compact   2985          28  22.7

 

 

ggplot2의 geom_point()와 scale_size_area() 함수를 사용하여 버블 그래프 (bubble chart)를 그려보겠습니다.  ggplot2는 별도의 설치와 호출이 필요한 패키지이므로 아래와 같이 install.packages()와 library()로 설치 및 호출을 먼저 해야 합니다.

 

> install.packages("ggplot2")
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/ggplot2_1.0.1.zip'
Content type 'application/zip' length 2676272 bytes (2.6 MB)
downloaded 2.6 MB

package ‘ggplot2’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
	C:\Users\user\AppData\Local\Temp\RtmpKeoxEa\downloaded_packages
> library(ggplot2) 

 

 

 

x축에는 무게(Weight)를, y축에는 고속도로연비(MPG.highway)를, 원의 크기는 가격(Price)를 설정하였습니다.  그리고 겹치는 부분이 있어서 alpha=0.5 로 해서 반투명하게 하였습니다. scale_size_area 에서 원의 크기의 최대값(max)을 15개 한정을 지었으며, geom_text() 함수를 활용해 vjust=1로 해서 x축 값에 align되고 y값은 MPG.highway값에 살짝 조정을 가해서 label로는 모델명(Model) 변수값을 가져다가 라벨링을 하였습니다.

 

> # Bubble chart with scale_size_area and label
> ggplot(Cars93_sample, aes(x=Weight, y=MPG.highway)) + 
+   geom_point(aes(size=Price), shape=21, colour="grey90", fill="yellow", , alpha=0.5) +
+   scale_size_area(max_size = 15) + # 범례 없애려면 guide=FALSE
+   geom_text(aes(y=as.numeric(MPG.highway)-sqrt(Price)/10, label=Model), 
+             vjust=1, colour="grey40", size=3) + 
+   ggtitle("Bubble chart with scale_size_area and label") 
 
 

 

 

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

 

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

 

  

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 2016.08.05 16:19  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  2. 조정호 2017.07.04 19:31  댓글주소  수정/삭제  댓글쓰기

    Rfriend님 질문이 또 생겼네요ㅎㅎ

    ggplot(Cars93_sample, aes(x=Weight, y=MPG.highway)) +
    geom_point(aes(size=Price), shape=21, colour="grey90", fill="yellow", alpha=0.5)+
    scale_size_area(max_size=15)+
    geom_text(aes(y=as.numeric(MPG.highway)-sqrt(Price)/10, label=Model),
    vjust=1, colour="grey40", size=3) +
    ggtitle("Bubble chart")

    이코드에서 geom_text의 위치가 왜 as.numeric(MPG.highway)-sqrt(Price)/10 이렇게 되는지 설명
    부탁드립니다.

    • R Friend R_Friend 2017.07.04 21:11 신고  댓글주소  수정/삭제

      안녕하세요 조정호님.

      문의하신 geom_text 위치를
      as.numeric(MPG.highway)-sqrt(Price)/10
      했던 이유는 Y 축의 값으로 MPG.highway 만 할 경우 서로 겹치는 것들이 있어서 'sqrt(Price)/10'를 추가하여 빼줌으로써 그래프 Y 축의 LABEL이 서로 어긋나게 하려고 했던거구요, 왜 'sqrt(Price)/10' 이냐 하면 그냥 적당한 위치를 찾다가 이렇게도 해보고 저렇게도 해보다가 trial & error 몇 번 해보고 그냥 이렇게 한것입니다. 무슨 학문적인 배경이나 이론... 이런 것은 없습니다. ^^; 본문의 그래프를 다시 유심히보니 Y축으로 중첩되는 것을 그리 잘 해결하지는 못해보이네요. ^^;;;

      다른 방식으로 더 좋은 방법, 수식이 있을 텐데요, 한번 아이디어를 내보시는 것도 재미있을 듯 합니다.

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

댓글을 달아 주세요

시간의 흐름에 따른 그룹/집단 별 관측값 혹은 비율의 변화를 누적해서 볼 수 있는 그래프가 누적 영역 그래프 (Stacked Area Plot) 입니다.   아마 엑셀에서 많이 보았을 법한 그래프 일것이라고 생각합니다.

 

2007년부터 2014년까지의 한국 수/출입 무역량 (단위: 1 B$) 데이터를 가지고 수출과 수입으로 구분하여서 ggplot2의 geom_area() 함수를 사용하여 누적 영역 그래프(Stacked Area Plot) 를 그려보도록 하겠습니다.

 

아래는 2007년부터 2014년까지의 한국 수/출입 무역량 (단위: 1 B$) 데이터를 링크해두었습니다.

(☞ 한국 수/출입 무역량 데이터 다운로드  trade_stat_07_14.csv)

* 출처 : 국가무역통계 KOSIS, http://kosis.kr/statisticsList/statisticsList_01List.jsp?vwcd=MT_ZTITLE&parmTabId=M_01_01#SubCont)

 

그래프를 그리기에 딱 맞는 형식이 아니므로 csv 데이터를 불러들인 다음에

 -> sqldf 패키지를 활용해 Year 단위로 수출입 실적을 집계

 -> 이때 단위를 1000$ -> 1B$ 로 바꿔주기 위해 1,000,000 으로 나눠줌

을써 데이터를 필요에 맞게 집계해보겠습니다.

 

> trade_stat <- read.csv("C:/Users/user/Documents/R/trade_stat_07_14.csv", # 경로 설정 + header = TRUE) > > > trade_stat <- transform(trade_stat, Year = substr(Time, 1, 4)) > > sapply(trade_stat, class) Time export_amt import_amt Year "numeric" "integer" "integer" "factor" > > library(sqldf) > # 한국 수/출입 무역금액, 단위: 1B$ > trade_stat_Year <- sqldf('select Year, + sum(export_amt)/100000 as exp_amt_Year, + sum(import_amt)/100000 as imp_amt_Year + from trade_stat + group by Year + order by Year + ') > trade_stat_Year Year exp_amt_Year imp_amt_Year 1 2007 3714 3568 2 2008 4220 4352 3 2009 3635 3230 4 2010 4663 4252 5 2011 5552 5244 6 2012 5478 5195 7 2013 5596 5155 8 2014 5726 5255

 

 

 

여기까지 했는데도 누적 영역 그래프를 그리기에 딱 맞는 데이터 형태가 아니라서 reshape 패키지의 melt() 함수를 사용하여 데이터를 현재의 가로로 늘어져있는 exp_amt_Year, imp_amt_Year 변수를 -> 세로로 세워서 데이터 구조를 변경해보겠습니다.

 

그 다음에 variable -> trade_cd (수입, 수출 구분 코드), value -> amount_B (무역금액, 단위 : 1B$) 로 변수명을 변경하였습니다.

 

> # 데이터 구조 녹이기(melt) - 세로로 세우기
> library(reshape)
> trade_stat_Year_melt <- melt(trade_stat_Year, idvars = c("Year"))
Using Year as id variables
> trade_stat_Year_melt
   Year     variable value
1  2007 exp_amt_Year  3714
2  2008 exp_amt_Year  4220
3  2009 exp_amt_Year  3635
4  2010 exp_amt_Year  4663
5  2011 exp_amt_Year  5552
6  2012 exp_amt_Year  5478
7  2013 exp_amt_Year  5596
8  2014 exp_amt_Year  5726
9  2007 imp_amt_Year  3568
10 2008 imp_amt_Year  4352
11 2009 imp_amt_Year  3230
12 2010 imp_amt_Year  4252
13 2011 imp_amt_Year  5244
14 2012 imp_amt_Year  5195
15 2013 imp_amt_Year  5155
16 2014 imp_amt_Year  5255
> 
> # 변수명 변경
> trade_stat_Year_melt <- rename(trade_stat_Year_melt, c(variable="trade_cd", value="amount_B"))
> trade_stat_Year_melt
   Year     trade_cd amount_B
1  2007 exp_amt_Year     3714
2  2008 exp_amt_Year     4220
3  2009 exp_amt_Year     3635
4  2010 exp_amt_Year     4663
5  2011 exp_amt_Year     5552
6  2012 exp_amt_Year     5478
7  2013 exp_amt_Year     5596
8  2014 exp_amt_Year     5726
9  2007 imp_amt_Year     3568
10 2008 imp_amt_Year     4352
11 2009 imp_amt_Year     3230
12 2010 imp_amt_Year     4252
13 2011 imp_amt_Year     5244
14 2012 imp_amt_Year     5195
15 2013 imp_amt_Year     5155
16 2014 imp_amt_Year     5255

 

 

 

이제 드디어 누적 영역 그래프를 그릴 데이터 셋 준비가 다 되었군요.  ggplot2의 geom_area() 함수를 사용하여 우선 값 기준으로 그리고, 다음으로 비율 기준으로도 그려보겠습니다.

 

geom_area(colour=NA)로 하고 geom_line(position="stack")으로 해서 양 옆에 선은 트여주고, 영역 간 경계선은 그려주었습니다.

 

> # 누적 영역 그래프 그리기
> ggplot(trade_stat_Year_melt, aes(x=Year, y=amount_B, fill=trade_cd, group=trade_cd)) +
+   geom_area(colour=NA, alpha=0.5) + # alpha 투명도
+   scale_fill_brewer(palette="Blues") +
+   geom_line(position="stack", size=0.3) + 
+   ggtitle("Stacked Area Plot of Trade (Import, Export) from 2007 to 2014")
ymax not defined: adjusting position using y instead
 

 

 

 

aes(arder=desc()) 를 사용하여 위의 영역 구분 그룹의 순서를 바꿀 수도 있습니다.  위의 예제에서는 exp_amt_Year (수출액)이 아래에 위치했습니다만, 아래 예제에서는 exp_amt_Year(수출액)이 위로 위치가 바뀌었음을 알 수 있습니다.

 

> # 누적 영역 순서 바꾸기
> library(plyr) # desc() 함수 사용 위해 필요
> ggplot(trade_stat_Year_melt, aes(x=Year, y=amount_B, fill=trade_cd, group=trade_cd, 
+                                  order=desc(trade_cd))) + # 누적 영역 순서 내림차순 정렬
+   geom_area(colour=NA, alpha=0.5) + # alpha 투명도
+   scale_fill_brewer(palette="Blues") +
+   geom_line(position="stack", size=0.3) + 
+   ggtitle("Stacked Area Plot of Trade (Import, Export) from 2007 to 2014")
ymax not defined: adjusting position using y instead

 

 

 

 

 

 


 

 

이번에는 비율 기준으로 해서 누적 영역 그래프를 그려보겠습니다.  이를 위해서는 데이터셋에서 Year 별로 비율을 계산해주어야 합니다.  데이터 프레임에서 사칙연산을 써가면서 transform() 함수로 step-by-step 해나갈 수도 있는데요, plyr패키지의 ddply() 함수를 사용하면 놀랍도록 간편하게 원하는 비율 값을 구할 수 있습니다.

 

> #-----
> # 비율 누적 영역 그래프 그리기
> # 비율 계산하기
> library(plyr)
> 
> trade_stat_Year_melt_prop <- ddply(trade_stat_Year_melt, 
+                                    "Year", transform, 
+                                    trade_prop = round(100*amount_B/sum(amount_B),1))
> 
> trade_stat_Year_melt_prop
   Year     trade_cd amount_B trade_prop
1  2007 exp_amt_Year     3714       51.0
2  2007 imp_amt_Year     3568       49.0
3  2008 exp_amt_Year     4220       49.2
4  2008 imp_amt_Year     4352       50.8
5  2009 exp_amt_Year     3635       52.9
6  2009 imp_amt_Year     3230       47.1
7  2010 exp_amt_Year     4663       52.3
8  2010 imp_amt_Year     4252       47.7
9  2011 exp_amt_Year     5552       51.4
10 2011 imp_amt_Year     5244       48.6
11 2012 exp_amt_Year     5478       51.3
12 2012 imp_amt_Year     5195       48.7
13 2013 exp_amt_Year     5596       52.1
14 2013 imp_amt_Year     5155       47.9
15 2014 exp_amt_Year     5726       52.1
16 2014 imp_amt_Year     5255       47.9

 

 

 

 

위의 trade_prop 변수를 활용해서 비율 누적 영역 그래프(Propostion stacked area plot)을 그려보도록 하겠습니다.  값을 기준으로 했을 때와 script는 동일하며, y값 자리에 trade_prop (수출입 무역 비율) 변수로 바꾸어주기만 하면 됩니다.

 

그래프 뒤에 단위 격자가 보이도록 geom_area(alpha=0.5) 로 해서 약간 투명하게 처리했습니다.

 

> # 비율 누적 영역 그래프 그리기
> library(plyr) # desc() 함수 사용 위해 필요
> ggplot(trade_stat_Year_melt_prop, aes(x=Year, y=trade_prop, fill=trade_cd, group=trade_cd, 
+                                  order=desc(trade_cd))) + # 누적 영역 순서 내림차순 정렬
+   geom_area(colour=NA, alpha=0.5) + # alpha 투명도
+   scale_fill_brewer(palette="Blues") +
+   geom_line(position="stack", size=0.3) + 
+   ggtitle("Stacked Area Plot of Trade Proportion (Import, Export) from 2007 to 2014")
ymax not defined: adjusting position using y instead

 

 

 

 

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

 

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

 

 

Posted by R Friend R_Friend

댓글을 달아 주세요

예전 포스팅 중에서 일변량 연속형 변수에 대해 ggplot2로 막대 그래프 그리는 법을 소개했었는데요, 막대 그래프의 훌륭한 대안으로서 점 그래프(Dot Plot)이 있습니다. 

 

Cleveland and McGill (1984) 이  “Graphical Methods for Data Presentation: Full Scale Breaks, Dot Charts, and Multibased Logging.” 이라는 논문에서 막대 그래프 대비 점 그래프가 데이터 해석, 가독성에서 가지는 우수성을 소개하면서 Cleveland Dot Plot 이라고도 많이 불리는 그래프입니다.

 

 

분석에 활용할 데이터는 MASS 패키지 내 Cars93 데이터 프레임에서, 차종(Type), 모델(Model), Max.Price, Min.Price의 4개 변수를 사용하겠으며, 관측치 개수가 많아서 화면 하나에 전부 뿌리기에는 너무 많으므로 차종(Type)의 Level 중에서 "Large", "Midsize", "Small" 만 선별하고 "Compact", "Sproty", "Van"은 제외하도록 하겠습니다.

 

 

> 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 ...
> table(Cars93$Type)

Compact   Large Midsize   Small  Sporty     Van 
     16      11      22      21      14       9 
> 
> # Model, Type, Max.Price, Min.Price 변수만 선택
> # Type 중에서 Large, Midsize, Small만 선택 (Compact, Sortry, Van은 제외)
> 
> Cars93_P <- subset(Cars93, 
+                      select = c(Model, Type, Min.Price, Max.Price), 
+                      subset = (Type %in% c("Large", "Midsize", "Small")))
> str(Cars93_P)
'data.frame':	54 obs. of  4 variables:
 $ Model    : Factor w/ 93 levels "100","190E","240",..: 49 56 1 6 24 54 74 73 35 79 ...
 $ Type     : Factor w/ 6 levels "Compact","Large",..: 4 3 3 3 3 2 2 3 2 3 ...
 $ Min.Price: num  12.9 29.2 30.8 23.7 14.2 19.9 22.6 26.3 33 37.5 ...
 $ Max.Price: num  18.8 38.7 44.6 36.2 17.3 21.7 24.9 26.3 36.3 42.7 ...
> head(Cars93_P)
    Model    Type Min.Price Max.Price
1 Integra   Small      12.9      18.8
2  Legend Midsize      29.2      38.7
4     100 Midsize      30.8      44.6
5    535i Midsize      23.7      36.2
6 Century Midsize      14.2      17.3
7 LeSabre   Large      19.9      21.7

 

 

 

geom_point() 함수를 사용하여 클리브랜드 점 그래프(Cleveland dot plot)을 그려보겠습니다. 

 

aes(y = reorder(Model, Max.Price)) 를 사용해서 y축에 사용할 Model 을 Max.Price 를 기준으로 정렬을 하였기 때문에 아래처럼 Max.Price가 높은 것부터 낮은 것으로 정렬이 된 채로 점 그래프가 제시되었습니다.

 

aes(shape = Type) 을 적용하여서 Type(Large, Midsize, Small) 별로 모양(shape)을 달리해서 제시하였습니다.

 

> # Cleveland dot plot of Max Price of Models with different shape by Type > library(ggplot2) > > ggplot(Cars93_P, aes(x = Max.Price, y = reorder(Model, Max.Price), shape = Type)) + + geom_point(size = 3, colour = "blue") + + theme_bw() + # background 색 없애기 + theme(panel.grid.major.x = element_blank(), # x축 선 없애기 + panel.grid.minor.x = element_blank(), + panel.grid.major.y = element_line(colour="grey90", linetype="dashed")) + + ggtitle("Cleveland dot plot of Max.Price of Models with different shape by Type")

 

 

 

 

 

 

다음으로, Type(Large, Midsize, Small) 별로 facet_grid(Type ~ ., scales="free_y", space="free_y") 을 적용하여 면을 분할을 한 클리브랜드 점 그래프(Cleveland dot plot)을 그려보겠습니다.

 

면 분할해서 그리려면 위의 예처럼 ggplot2 내 aes(reorder)로는 안되구요, 먼저 Type과 Max.Price 순서대로 데이터셋을 따로 정렬해서 요인(factor)으로 levels 를 지정해서 변환해주어야 합니다.  그래프는 상대적으로 쉬운데, 데이터셋 정렬/요인변환이 어려울 수 있겠습니다.

 

> # Type, Max.Price 순서대로 정렬
> Model_Order <- Cars93_P$Model[order(Cars93_P$Type, # Large, Midsize, Small 순서
+                                     -Cars93_P$Max.Price, # 높은것에서 낮은 순서
+                                     decreasing=TRUE)]
> 
> # Model_Order를 요인(factor)으로 변환
> Cars93_P$Model <- factor(Cars93_P$Model, levels=Model_Order)
> 
> # Type별로 면 분할, Max.Price 순서대로 정렬된 Cleveland dot plot
> ggplot(Cars93_P, aes(x = Max.Price, y = Model)) +
+   geom_point(size = 3, aes(colour = Type)) +
+   theme_bw() +
+   theme(panel.grid.major.y = element_blank(), 
+         panel.grid.minor.y = element_blank()) + 
+   facet_grid(Type ~ ., scales="free_y", space="free_y") +
+   ggtitle("Cleveland dot plot of Max.Price of Models with Facets of Type")

 

 

 

 

 

다음으로, 차종(Type)별로 면 분할은 유지하면서 위의 Max.Price 에 더해서 Min.Price 를 추가하고 모양(shape)을 다르게 제시해보겠습니다.

 

이것도 데이터셋을 따로 미리 손을 봐줘야 합니다.  reshape 패키지의 melt() 함수를 사용해서 Max.Price, Min.Price 두 값을 Price_cd (Max.Price, Min.Price)와 Price (value) 의 두개 변수로 녹여서 데이터 구조를 ggplot2의 geom_point()에 사용할 수 있도록 변경하여야 합니다.  (reshape 패키지의 melt(), cast() 함수는 여기서 자세히 설명하기가 힘든데요, 따로 알아보시면 좋겠습니다)

 

 

> #--------
> # Min.Price 추가 
> # melt
> library(reshape)
> Cars93_P_melt <- melt(Cars93_P, idvars = c("Type", "Model"))
Using Model, Type as id variables
> head(Cars93_P_melt)
    Model    Type  variable value
1 Integra   Small Min.Price  12.9
2  Legend Midsize Min.Price  29.2
3     100 Midsize Min.Price  30.8
4    535i Midsize Min.Price  23.7
5 Century Midsize Min.Price  14.2
6 LeSabre   Large Min.Price  19.9
> 
> # 변수명 변경
> Cars93_P_melt <- rename(Cars93_P_melt, c(variable = "Price_cd", value = "Price"))
> head(Cars93_P_melt)
    Model    Type  Price_cd Price
1 Integra   Small Min.Price  12.9
2  Legend Midsize Min.Price  29.2
3     100 Midsize Min.Price  30.8
4    535i Midsize Min.Price  23.7
5 Century Midsize Min.Price  14.2
6 LeSabre   Large Min.Price  19.9
> 
> # Type별로 면 분할, Max.Price 순서대로 정렬, Min.Price추가된 Cleveland dot plot
> ggplot(Cars93_P_melt, aes(x = Price, y = Model)) + 
+   geom_segment(aes(yend=Model, xend=0)) + # 점까지만 선 그리기
+   geom_point(size=3, aes(shape = Price_cd)) + # Price_cd로 모양 구분
+   theme_bw() + # backgroud 색 없애기
+   theme(panel.grid.major.y = element_blank(), # y축 없애기
+         panel.grid.minor.y = element_blank()) + # y축 없애기
+   facet_grid(Type ~ ., scales="free_y", space="free_y") + # Type별로 면 분할
+   ggtitle("Cleveland dot plot of Max, Min Price of Models with Facets of Type")
 

 

 

 

위의 세번째 그래프처럼 Max.Price와 Min.Price를 같은 그래프에 그리는데, 만약 이것을 막대 그래프로 그린다고 상상해 보세요.  막대그래프로 그린다면 지저분하고 해석, 가독성이 클리브랜드 점 그래프 대비 떨어질겁니다. 

 


 

[Reference]

 

Cleveland, William S. 1984. “Graphical Methods for Data Presentation: Full Scale
Breaks, Dot Charts, and Multibased Logging.” The American Statistician, 38:270-280.

 

Dot Plots: A Useful Alternative to Bar Charts, Naomi B. Robbins, Ph.D. March 7, 2006

 

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 김경찬 2017.02.04 17:02  댓글주소  수정/삭제  댓글쓰기

    와~ 점그래프 그리는건 정말 어렵네요. segment함수의 매개변수 왜 저렇게 두는지도 모르겠고 ㅎㅎ 외우기는 정말 어려운듯하네요ㅠㅠ

    • R Friend R_Friend 2017.02.04 17:23 신고  댓글주소  수정/삭제

      젇 함수를 전부 다 외우지는 못합니다. 필요할 때 블로그 보면서 만들고 싶은 형태 골라서 R scriot 짜요.

      클리브랜드 점 그래프 유용해서 종종 쓰은 편이예요.

      엑셀 그래프 대비 R이 좋은 점이 바로 이런거죠. 데이터 전처리 하고 세부 옵션으로 조정해 가면서 바로 인쇄에 써먹어도 될 정도의 고품질 그래프를 스릴 수 있다는거요.

 

2개의 연속형 변수를 가지고 그릴 수 있는 그래프 중에 이차원 밀도 그래프 (2D Density Plot) 을 ggplot2의 stat_density2d() 함수를 이용하여 그려보겠습니다. 

 

 

이차원 밀도 그래프 (2D Density Plot)은 2D 커널 밀도 추정치를 구해서 같은 추정치를 선으로 연결한 그래프 입니다. 

 

 

우리가 일상 생활 중에 자주 쉽게 접하는 이차원 밀도 그래프의 예로는 지도의 등고선이나 일기예보할 때 쓰는 등압선이 있습니다.

 

 

[ 기상청 등압선 얘시 ]

 

 

* 출처: 기상청, http://www.kma.go.kr/weather/images/analysischart.jsp

 

 

이번에 R로 예를 들  데이터는 뉴욕의 기상을 19 73년 5월부터 9월까지 매일 측정한 airquality 데이터 프레임에서 5월달과 7월달 두 달의 Wind, Temp를 사용하겠습니다.

 

(airquality는 시계열 데이터이고, 이전 포스팅에서 airquality 데이터 프레임을 사용하여 ggplot2로 시계열 그래프 그래프 그리는 법 설명하였으니 참고하시기 바랍니다)

 

먼저, airquality의 데이터 구조를 살펴보고, 5월달과 7월달 데이터만 선별해서 새로운 데이터 프레임을 만들어보겠습니다.

 

 

> # airquality 구조
> 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 ...
> 
> # 5월과 7월만 선택
> airquality_May_July <- subset(airquality, 
+                               select = c(Month, Day, Wind, Temp), 
+                               subset = (Month %in% c(5, 7)))
 
>
>
> head(airquality_May_July)
  Month Day Wind Temp
1     5   1  7.4   67
2     5   2  8.0   72
3     5   3 12.6   74
4     5   4 11.5   62
5     5   5 14.3   56
6     5   6 14.9   66
>
>
> tail(airquality_May_July)
   Month Day Wind Temp
87     7  26  8.6   82
88     7  27 12.0   86
89     7  28  7.4   88
90     7  29  7.4   86
91     7  30  7.4   83
92     7  31  9.2   81

 

 

 

이제 이차원 밀도 그래프 (2D Density Plot)을 그려보겠습니다.  그리고 5월과 7월달의 Month를 색깔로 구분하여 보겠습니다.

 

이때 조심해야 할 것이 있습니다.  aes() 에 shape이나 colour 에는 범주형변수(factor)가 들어가야 합니다.  만약 연속형 변수가 들어가면  "Error: A continuous variable can not be mapped to shape" 라는 에러 메시지가 뜹니다.

 

> # 2차원 밀도 그래프 : 모양과 색깔로 구분
> # 연속형 변수라서 error
> ggplot(data=airquality_May_July, aes(x=Wind, y=Temp, shape=Month)) +
+   geom_point() + 
+   stat_density2d() +
+   ggtitle("2D desity plot of Wind and Tmep, at May and July")
Error: A continuous variable can not be mapped to shape

 

 

 

Month를 Month.ch라는 새로운 문자형 변수로 변환해, 이를 사용해서 이차원 밀도 그래프를 Month별로 모양과 색깔을 구분해서 그려보겠습니다.  

 

> # Month를 문자형 변수로 변환
> airquality_May_July <- transform(airquality_May_July, Month.ch = as.character(Month))
> 
> sapply(airquality_May_July, class)
      Month         Day        Wind        Temp    Month.ch 
  "integer"   "integer"   "numeric"   "integer" "character"
> 
> head(airquality_May_July)
  Month Day Wind Temp Month.ch
1     5   1  7.4   67        5
2     5   2  8.0   72        5
3     5   3 12.6   74        5
4     5   4 11.5   62        5
5     5   5 14.3   56        5
6     5   6 14.9   66        5

 

 

 

stat_density2d() 함수로 커널 밀도 추정치를 계산해서 2차원 밀도 그래프를 그리면,

 

> # 2차원 밀도 그래프 : Month를 모양으로 구분
> ggplot(data=airquality_May_July, aes(x=Wind, y=Temp, shape=Month.ch)) +
+   geom_point(size=4) + 
+   stat_density2d() +
+   ggtitle("2D desity plot of Wind and Tmep, May/July by Shape")
> 

 

 


 

> # 2차원 밀도 그래프 : Month를 색깔로 구분 > ggplot(data=airquality_May_July, aes(x=Wind, y=Temp, colour=Month.ch)) + + geom_point(size=4) + + stat_density2d() + + ggtitle("2D desity plot of Wind and Tmep, at May/July by Colour")

 

 

 

 

 

 

 

 

이번에는 (범례가 있기는 합니다만) 사용자의 가독성을 조금 더 높여주기 위해 2차원 밀도 그래프의 5월, 7월 두 집단의 중앙 부위에 년/월을 annotate()의 "text"로 라벨을 추가해 보겠습니다.

 

> # 2차원 밀도 그래프 : Month를 색깔로 구분, 년/월 라벨 추가
> ggplot(data=airquality_May_July, aes(x=Wind, y=Temp, colour=Month.ch)) +
+   geom_point(size=4) + 
+   stat_density2d() +
+   ggtitle("2D desity plot of Wind and Tmep, at1973. May/July by Colour") +
+   annotate("text", x=11, y=65, label="1973.May", alpha=0.5) + 
+   annotate("text", x=9, y= 83, label="1973.July", alpha=0.5)

 

 

 

 

 

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

 

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

 

Posted by R Friend R_Friend

댓글을 달아 주세요