x축과 y축으로 나타낸 그래프 혹은 2차원의 지도 위에 특정 연속형 변수의 값에 따라 색깔을 조금씩 다르게 하여 정보를 보여주는 시각화 방법으로 히트맵(Heat map)이 많이 사용됩니다. 

 

R ggplot2 패키지에서는 geom_tile(), geom_raster() 함수를 사용해서 쉽고 편하게 히트맵(Heat map)을 그릴 수 있습니다. 

 

이번 포스팅에서는 히트맵(Heat map)을 그리고, 축의 항목 위치를 바꾸어 보는 것을 예를 들어보이겠습니다.

 

아래 보시는 것은 구글에 히트맵(Heat map) 이라는 키워드로 나온 이미지들인데요, 평소에 알게 모르게 히트맵을 우리가 많이 접하고 있었다는 것을 알 수 있을 것입니다.

 

 

[히트맵 (Heat map) 예시 ]

 

* 이미지 출처 : 구글(www.google.co.kr)

 

 

MASS 패키지에 내장되어 있는 Cars93 데이터 프레임이며, 차종(Type), 실린더(Cylinders) 별 고속도로연비(MPG.highway) 를 사용하여 히트맵(Heat map)을 그려보겠습니다.

 

 

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

 

 

 

x축에 차종(Type), y축에 실린더개수(Cylinders)별로 고속도로연비(MPG.highway)에 따라서 색을 달리하여 히트맵을 geom_tile() 함수를 사용해 그려보겠습니다.

 

 
> # Type, Cylinders 별 MPG.highway Heatmap : geom_tile()
> a1 <- ggplot(Cars93, aes(x=Type, y=Cylinders, fill=MPG.highway)) +
+   geom_tile()
> 
> a1

 

 

 

 

 

위의 히트맵을 보면 x축에 차종(Type)이 차의 크기 순서가 아니라 알파벳 순서로 되어 있다보니 색깔이 경향성이 없이 무작위하게 채워져있어 보입니다.  x축을 차의 크기를 감안한 순서대로, 즉, "Small", "Compact", "Midsize", "Sporty", "Large", "Van" 의 순서대로 scale_x_discrete(limits=...) 를 사용해 바꾸어보겠습니다.

 

 
> # x축 순서 바꾸기 : scale_x_discrete(limits=...)
> a2 <- a1 + 
+   scale_x_discrete(limits=c("Small", "Compact", "Midsize", "Sporty", "Large", "Van"))
> 
> a2

 

 

 

 

 

위의 히트맵을 보니 크기가 작을 수록, 실린더 개수가 작을 수록 고속도로 연비가 높으며, 그 반대는 고속도로 연비가 낮아짐을 한눈에 단박에 파악할 수 있게 되었습니다.

 

 

이번에는 geom_raster() 함수를 사용해 히트맵을 그려보겠습니다.  결과적으로 geom_tile()과 차이가 거의 없다는 것을 알 수 있습니다.

 

 
> # Type, Cylinders 별 MPG.highway Heatmap : geom_raster()
> ggplot(Cars93, aes(x=Type, y=Cylinders, fill=MPG.highway)) +
+   geom_raster() + 
+   scale_x_discrete(limits=c("Small", "Compact", "Midsize", "Sporty", "Large", "Van"))

 

 

 

 

 


연속형 숫자형 값을 가지는 히트맵의 색상을 scale_fill_gradient(low = "colour 1", high = "colour 2") 옵션을 사용해서 다르게 설정해보도록 하겠습니다. (kusscd 님, 댓글로 방법 공유해주셔서 감사합니다 ^^)



> ggplot(Cars93, aes(x=Type, y=Cylinders, fill=MPG.highway)) + # filling with numeric value

+   geom_tile() +

+   scale_x_discrete(limits = c("Small", "Compact", "Midsize", "Sporty", "Large", "Van")) +

+   scale_fill_gradient(low = "yellow", high = "red") +

+   ggtitle("Heatmap of MPG.highway by Type & Cylinders")


 






다음으로, 범주형 자료로 히트맵의 색상을 채우는 경우에 scale_fill_manual(values = c("colour 1", "colour 2", ...) 을 옵션을 사용해서 색상을 사용자가 직접 지정해주는 방법을 2개 범주를 가지는 간단한 예시를 들어서 설명하겠습니다. 



> my.df <- data.frame(XCoord = c(1, 1, 2, 3, 3, 4, 4, 5, 5, 5), 

+                     YCoord = c(1, 4, 3, 1, 3, 1, 5, 2, 3, 5), 

+                     Seg = c("A", "A", "A", "A", "B", "A", "B", "B", "B", "B"))

> ggplot(my.df, aes(x=XCoord, y=YCoord, fill=Seg)) + # filling with categorical value

+   geom_tile(colour="white") +

+   scale_fill_manual(values = c("blue", "red")) +

+   ggtitle("Heatmap with 2 categories with scale_fill_manual()")




 



 

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

 

Posted by R Friend Rfriend

댓글을 달아 주세요

  1. kusscd 2017.06.22 19:15  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 유용한 정보 정말 잘 쓰고 있습니다.!
    위의 색 같은 경우 ~~~ + scale_fill_gradient(low = "yellow", high = "red")
    처럼 하면 보통 많이 보는 색을 얻을 수 있을 것 같네용

  2. jiwon 2017.12.16 13:53  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 블로그 잘 보고 있습니다!
    궁금한 게 있는데, 저기 히트맵에 색칠되는 건 차종과 실린더의 연비 평균인가요?
    그러니까 예를 들면 차종이 스몰이고 실린더가 4이면 MPG.highway 값이 여러개가 나오는데
    이걸 평균내서 색칠이 되는 건지 궁금합니다.

  3. 황아재 2019.08.26 14:50  댓글주소  수정/삭제  댓글쓰기

    geom_raster로 그래프를 그리는데 고도별 온도 그래프를 그리는데 고도가 일정하게 증가하는 것이 아니어서인지 거의 point 함수에 색을 입혀놓은 수준이 되어버리더라고요.
    log 스케일로 변환도 해보았지만 일정하게 증가하는 값이 아니라고 판단한건지 똑같이 되더라구요.
    혹시 해결방법을 알고계신가요??

  4. 황아재 2019.08.26 15:41  댓글주소  수정/삭제  댓글쓰기

    스팸방지패턴에 의해 올릴 수가 없다고 나오네요.
    구글링을 통해서 조금 다른 방법을 찾아보고 다른 방안이 없을 때 다시 올려드리도록 하겠습니다.

범주형 변수의 그룹(요인)을 x 축으로 한 그래프를 그리면 디폴트는 알파벳 순서대로 그룹이 제시가 됩니다.  만약 순서형 요인(ordered factor)으로 범주형 변수를 만들었다면 그 순서에 따라서 그래프가 그려질 겁니다. 

 

그런데 분석가가 범주형 변수의 그룹의 순서를 ggplot2가 디폴트로 그려준 것과는 달리 바꾸고 싶어할 수 있습니다. 

 

이때 scale_x_discrete(limits=c(...) 함수를 사용해서 그룹의 순서를 바꿀 수 있습니다.

 

 

아래의 예제에 사용할 데이터는 iris 데이터프레임의 Petal.Length 와 Species 두 개의 변수입니다. Species 가 요인(Factor)형 변수이며, "setosa", "versicolor", "virginica" 의 3개 Levels 로 구성이 되어있습니다.

 

 
> 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 패키지를 사용해서 Species를 x축으로 Petal.Length 를 y축으로 해서 Box plot을 그려보겠습니다.  이를 위해서 먼저 데이터셋을 ggplot2에서 사용할 수 있는 형태로 변환이 필요합니다.  가로로 옆으로 늘어서있는 원래의 iris 데이터셋을 reshape 패키지를 사용해서 melt() 함수를 적용하여 세로로 길게 세워보겠습니다. (☞ reshape 패키지 melt(), cast() 함수 사용법 둘러보기)

 

 
> # dataset preparation
> library(reshape)
> iris_melt_petal.length <- melt(data=iris, 
+                   id.vars = c("Species"), 
+                   measure.vars = c("Petal.Length"))
> 
> iris_melt_petal.length
       Species     variable value
1       setosa Petal.Length   1.4
2       setosa Petal.Length   1.4
3       setosa Petal.Length   1.3
4       setosa Petal.Length   1.5
5       setosa Petal.Length   1.4
6       setosa Petal.Length   1.7
7       setosa Petal.Length   1.4
8       setosa Petal.Length   1.5
9       setosa Petal.Length   1.4
10      setosa Petal.Length   1.5
11      setosa Petal.Length   1.5
12      setosa Petal.Length   1.6
13      setosa Petal.Length   1.4
14      setosa Petal.Length   1.1
15      setosa Petal.Length   1.2
16      setosa Petal.Length   1.5
17      setosa Petal.Length   1.3
18      setosa Petal.Length   1.4
19      setosa Petal.Length   1.7
20      setosa Petal.Length   1.5
21      setosa Petal.Length   1.7
22      setosa Petal.Length   1.5
23      setosa Petal.Length   1.0
24      setosa Petal.Length   1.7
25      setosa Petal.Length   1.9
26      setosa Petal.Length   1.6
27      setosa Petal.Length   1.6
28      setosa Petal.Length   1.5
29      setosa Petal.Length   1.4
30      setosa Petal.Length   1.6
31      setosa Petal.Length   1.6
32      setosa Petal.Length   1.5
33      setosa Petal.Length   1.5
34      setosa Petal.Length   1.4
35      setosa Petal.Length   1.5
36      setosa Petal.Length   1.2
37      setosa Petal.Length   1.3
38      setosa Petal.Length   1.4
39      setosa Petal.Length   1.3
40      setosa Petal.Length   1.5
41      setosa Petal.Length   1.3
42      setosa Petal.Length   1.3
43      setosa Petal.Length   1.3
44      setosa Petal.Length   1.6
45      setosa Petal.Length   1.9
46      setosa Petal.Length   1.4
47      setosa Petal.Length   1.6
48      setosa Petal.Length   1.4
49      setosa Petal.Length   1.5
50      setosa Petal.Length   1.4
51  versicolor Petal.Length   4.7
52  versicolor Petal.Length   4.5
53  versicolor Petal.Length   4.9
54  versicolor Petal.Length   4.0
55  versicolor Petal.Length   4.6
56  versicolor Petal.Length   4.5
57  versicolor Petal.Length   4.7
58  versicolor Petal.Length   3.3
59  versicolor Petal.Length   4.6
60  versicolor Petal.Length   3.9
61  versicolor Petal.Length   3.5
62  versicolor Petal.Length   4.2
63  versicolor Petal.Length   4.0
64  versicolor Petal.Length   4.7
65  versicolor Petal.Length   3.6
66  versicolor Petal.Length   4.4
67  versicolor Petal.Length   4.5
68  versicolor Petal.Length   4.1
69  versicolor Petal.Length   4.5
70  versicolor Petal.Length   3.9
71  versicolor Petal.Length   4.8
72  versicolor Petal.Length   4.0
73  versicolor Petal.Length   4.9
74  versicolor Petal.Length   4.7
75  versicolor Petal.Length   4.3
76  versicolor Petal.Length   4.4
77  versicolor Petal.Length   4.8
78  versicolor Petal.Length   5.0
79  versicolor Petal.Length   4.5
80  versicolor Petal.Length   3.5
81  versicolor Petal.Length   3.8
82  versicolor Petal.Length   3.7
83  versicolor Petal.Length   3.9
84  versicolor Petal.Length   5.1
85  versicolor Petal.Length   4.5
86  versicolor Petal.Length   4.5
87  versicolor Petal.Length   4.7
88  versicolor Petal.Length   4.4
89  versicolor Petal.Length   4.1
90  versicolor Petal.Length   4.0
91  versicolor Petal.Length   4.4
92  versicolor Petal.Length   4.6
93  versicolor Petal.Length   4.0
94  versicolor Petal.Length   3.3
95  versicolor Petal.Length   4.2
96  versicolor Petal.Length   4.2
97  versicolor Petal.Length   4.2
98  versicolor Petal.Length   4.3
99  versicolor Petal.Length   3.0
100 versicolor Petal.Length   4.1
101  virginica Petal.Length   6.0
102  virginica Petal.Length   5.1
103  virginica Petal.Length   5.9
104  virginica Petal.Length   5.6
105  virginica Petal.Length   5.8
106  virginica Petal.Length   6.6
107  virginica Petal.Length   4.5
108  virginica Petal.Length   6.3
109  virginica Petal.Length   5.8
110  virginica Petal.Length   6.1
111  virginica Petal.Length   5.1
112  virginica Petal.Length   5.3
113  virginica Petal.Length   5.5
114  virginica Petal.Length   5.0
115  virginica Petal.Length   5.1
116  virginica Petal.Length   5.3
117  virginica Petal.Length   5.5
118  virginica Petal.Length   6.7
119  virginica Petal.Length   6.9
120  virginica Petal.Length   5.0
121  virginica Petal.Length   5.7
122  virginica Petal.Length   4.9
123  virginica Petal.Length   6.7
124  virginica Petal.Length   4.9
125  virginica Petal.Length   5.7
126  virginica Petal.Length   6.0
127  virginica Petal.Length   4.8
128  virginica Petal.Length   4.9
129  virginica Petal.Length   5.6
130  virginica Petal.Length   5.8
131  virginica Petal.Length   6.1
132  virginica Petal.Length   6.4
133  virginica Petal.Length   5.6
134  virginica Petal.Length   5.1
135  virginica Petal.Length   5.6
136  virginica Petal.Length   6.1
137  virginica Petal.Length   5.6
138  virginica Petal.Length   5.5
139  virginica Petal.Length   4.8
140  virginica Petal.Length   5.4
141  virginica Petal.Length   5.6
142  virginica Petal.Length   5.1
143  virginica Petal.Length   5.1
144  virginica Petal.Length   5.9
145  virginica Petal.Length   5.7
146  virginica Petal.Length   5.2
147  virginica Petal.Length   5.0
148  virginica Petal.Length   5.2
149  virginica Petal.Length   5.4
150  virginica Petal.Length   5.1

 

 

 

 

데이터셋 준비가 되었으므로, 디폴트 설정으로 해서 x축에 Species, y축에 Petal.Length로 Box plot 을 그려보겠습니다.  ggplot2는 별도의 설치 및 호출이 필요하므로 install.packages("ggplot2")와 library(ggplot2)를 먼저 실행 후 그래프를 그립니다.  x축의 요인(factor)의 순서가 위에서 살펴본것처럼 "setosa", "versicolor", "virginica"  의 알파벳 순서로 되어있습니다.

 

 

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

> # Boxplot of Petal.Length > f1 <- ggplot(iris_melt_petal.length, aes(x=Species, y=value)) + + geom_boxplot() + + ggtitle(("Boxplot of Petal.Length")) > f1

 

 

 

 

 

 

 

이것을 분석가가 필요에 따라서 순서를 "virginica", "versicolor", "setosa" 처럼 바꾸고 싶다고 해봅시다.  이때 사용하는 것이 scale_x_discrete(limit=...) 함수입니다.

 

 
> f2 <- f1 + 
+   scale_x_discrete(limits=c("virginica", "versicolor", "setosa")) + 
+   ggtitle("Changed Order of x axis by scale_x_discrete(limit=...)")
> 
> f2

 

 

 

 

 

첫번째에 디폴트로 그린 박스그림과 두번째에 범주형 축 그룹 순서를 바꾼 그래프의 차이를 아시겠지요?  많은 도움 되었기를 바랍니다.

 

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

 

Posted by R Friend Rfriend

댓글을 달아 주세요

  1. sigmaseo 2019.11.22 11:01  댓글주소  수정/삭제  댓글쓰기


    # melting하지 않고
    평소 Boxplot 그리듯이 하여 scale_x_discrete()함수를 넣어도 심플하게 그려지네요

    ggplot(iris, aes(x=Species, y=Petal.Length)) +
    geom_boxplot() +
    scale_x_discrete(limits=c("virginica", "versicolor", "setosa")) +
    ggtitle(("Boxplot of Petal.Length"))

이전 포스팅에서 하나의 그래프에 텍스트, 선, 화살표, 음영있는 사각형 등으로 부연 설명을 추가하기 위해 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 Rfriend

댓글을 달아 주세요

 

 

R에서 특정 조건을 만족하는지의 조건을 주고 뒤에 이어지는 표현식을 반복적으로 수행하게 하는 조건 연산 프로그래밍에 대해 알아보겠습니다.

 

 

 

먼저 한개의 숫자형 값에 대해 이것이 짝수인지 홀수인지 판단하는 R program을 짜보도록 하겠습니다.

 

 

 

 


  • 하나의 값에 대한 판단인 경우 : 

    if( 조건1 ) {
              표현식 1
    } else if (조건2) {
              표현식 2
    } else {
              표현식 3
    }

  

[ 짝수, 홀수 여부 판단 프로세스 ]

 

 

(1) 하나의 논리값에 대한 판단인 경우 : if()

 

> ## 하나의 논리값에 대한 판단
> # if()
> x1 <- c(4)
> if (x1 %% 2 == 0) {
+   y1 = c("Even Number")
+   print(y1)
+ } else {
+     y1 = c("Odd Number")
+     print(y1)
+ }
[1] "Even Number"

 

 

> x2 <- c(5)
> if (x2 %% 2 == 0) {
+   y2 = "Even Number"
+   print(y2)
+ } else {
+   y2 = "Odd Number"
+   print(y2)
+ }
[1] "Odd Number"
 

위의 2개의 예에서는 x1 이 4일 때 "Even Number"라고 판단했고, x2가 5일 때 "Odd Number"라고 잘 판단하였습니다.

 

하지만, 아래의 예제처럼 두개 이상의 논리값 벡터를 사용하는 경우에는 오류가 발생하게 되며, 아래 예제에서 보면 1~5까지 숫자 중에서 제일 처음으로 나오는 1에만 아래의 조건연산 프로그램이 적용되었고 두번째부터는 적용이 안되었습니다.  이럴 때는 ifelse() 문을 사용하여야 합니다

 

> # Error
> x3 <- c(1, 2, 3, 4, 5)
> if (x3 %% 2 == 0) {
+   y3 = "Even Number"
+   print(y3)
+ } else {
+   y3 = "Odd Number"
+   print(y3)
+ }
[1] "Odd Number"
Warning message:
In if (x3%%2 == 0) { :
  the condition has length > 1 and only the first element will be used

 



 

(2) 두개 이상의 논리값 벡터에 대한 판단 : ifelse()

 

  • 두개 이상의 논리값 벡터에 대한 판단인 경우 :

    ifelse( 조건1, 표현식1, 
          ifelse( 조건2, 표현식2, 
                 ifelse( 조건3, 표현식3, 표현식4)
                 ) 
           )
  •  

    위와 동일하게 1~5의 숫자에 대해서 이번에는 ifelse() 문을 사용해서 짝수, 홀수 여부를 판단하게 하고, 이를 데이터프레임 구조로 변환해서 view해보겠습니다.

     

    > ## vector 에 대한 판단
    > # 홀수/짝수 여부 판단 : ifelse( condition, expression 1, expression 2 )
    > x <- c(1, 2, 3, 4, 5)
    > z <- ifelse(x%%2 == 0, "Even Number", "Odd Number")
    > xz <- data.frame(x, z)
    > xz
      x           z
    1 1  Odd Number
    2 2 Even Number
    3 3  Odd Number
    4 4 Even Number
    5 5  Odd Number

     

     

     


     

     

    이번에는 양수, 0, 음수 인지 여부를 판단한 후 원래 벡터와 판단하는 프로그램을 ifelse()를 사용하여 짜보도록 하겠습니다.

     

    [ 양수, 0, 음수 인지 여부 판단하는 프로세스 ]

     

     

    > # 양수, 0, 음수인지 여부 판단 : ifelse( condition, expression 1, expression 2 ) > x <- c(-2, -1, 0, 1, 2) > y <- ifelse( x > 0, "Positive", + ifelse( x == 0, "Zero", "Negative") + ) > > xy <- data.frame(x, y) > > xy x y 1 -2 Negative 2 -1 Negative 3 0 Zero 4 1 Positive 5 2 Positive 

     

     


     

    To 산낙지님,

    제가 가족 여행다녀오느라 이제서야 집에 와서 댓글 달려고 막 하는 와중에...댓글을 삭제하셨네요. ^^;

    3가지 조건을 주어서 1, 0 혹은 yes, no 범주형 dummy 변수를 생성하는 방법은 아래를 참고하세요.

    MASS 패키지의 Cars93데이터프레임을 가지고 예를 들었습니다.

    [예제] "차종(Type)이 "Campact" 이고 & 가격(Price)이 16이하이고 & 고속도로연비(MPG.highway)가 30이상이면 1, 그 외는 모두 0인 변수 sub_yn 을 만드시오"

    ## Making dummy variable using ifelse() and transform()
    library(MASS)
    str(Cars93)
    summary(Cars93$Price)
    summary(Cars93$MPG.highway)

    Cars93 <- transform(Cars93,
                               sub_yn = ifelse(Type == c("Compact")
                                                   & Price <= 16
                                                   & MPG.highway >= 30, 1, 0))

     

     

     

     

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

     

     

    Posted by R Friend Rfriend

    댓글을 달아 주세요

    1. R Friend Rfriend 2016.10.03 19:03 신고  댓글주소  수정/삭제  댓글쓰기

      To 산낙지님,

      제가 가족 여행다녀오느라 이제서야 집에 와서 댓글 달려고 막 하는 와중에...댓글을 삭제하셨네요. ^^;

      3가지 조건을 주어서 1, 0 혹은 yes, no 범주형 dummy 변수를 생성하는 방법은 아래를 참고하세요.

      MASS 패키지의 Cars93데이터프레임을 가지고 예를 들었습니다.

      [예제] "차종(Type)이 "Campact" 이고 & 가격(Price)이 16이하이고 & 고속도로연비(MPG.highway)가 30이상이면 1, 그 외는 모두 0인 변수 sub_yn 을 만드시오"

      ## Making dummy variable using ifelse() and transform()
      library(MASS)
      str(Cars93)
      summary(Cars93$Price)
      summary(Cars93$MPG.highway)

      Cars93 <- transform(Cars93,
      sub_yn = ifelse(Type == c("Compact")
      & Price <= 16
      & MPG.highway >= 30, 1, 0))

      • 산낙지 2016.10.03 20:24  댓글주소  수정/삭제

        아 제가 방명록에 다시 달려고 댓글을 삭제했는데 여기에 달으셨군요 ^^; 댓글 삭제해서 죄송하고 답변 정말 감사합니다~~ 많은 참고 하겠습니다!

    2. 정현복 2017.01.06 17:56  댓글주소  수정/삭제  댓글쓰기

      a=c(1,2,NA,NA,3,5)
      b=c(2,4,5,6,7,8)
      ab=cbind(a,b)
      ab=as.data.frame(ab)
      class(ab)

      if (is.na(ab$a)=TRUE) ab$a=0 else ab$a=1
      if (is.na(ab$a)) ab$a=0 else ab$a=1
      if(ab$a==NA) {ab$a=0} else {ab$a=1}
      ab$a=ifelse(is.na(ab$a),0,1)

      안녕하세요 제가 코딩을 해보가 if문을 사용하는데 아무리 고쳐보고 책찾아보고 해도 도대체 왜 않되는지 모르겠습니다 맨마지막 코딩은 비로서 실행이 되는데 저거는 실행이 된다면 그러면 위에 if문들은 왜 않되는건지 도저히 이해가 않됩니다 도와주세요 ㅠㅠ

    3. 정현복 2017.01.09 23:54  댓글주소  수정/삭제  댓글쓰기

      글쓴이분 정말감사해요
      근데 1가지 정말 해결해주실수 잇나요
      데이터 테이블인데 지금
      gender변수안에 m f 가 팩터로 들어가 있는데 저는 그 변수값을 m이면 1 f면 0으로 넣고싶은데 어떻게 해야 할까요 이것도 찾아보고 저것도 찾아보고 3시간넘게 사투중인데 공모전 준비하는데 ㅠㅠ
      너무 힘들어요 아진짜 ㅠㅠㅠ제발 도와주세요 ㅠㅠ

      • R Friend Rfriend 2017.01.10 00:33 신고  댓글주소  수정/삭제

        정현복님, transform()과 elif() 함수가지고 간단한 예제 R script 짜보았습니다. 참고하세요.

        # making an example dataframe
        cust_id <- c(1, 2, 3, 4, 5, 6)
        gender <- c("F", "M", "F", "F", "M", "F")
        age <- c(23, 28, 42, 34, 45, 36)

        cust_df <- data.frame(cust_id, gender, age)

        # data structure check
        str(cust_df)

        # transforming by ifelse() function
        cust_df <- transform(cust_df, gender_new = ifelse(gender == "M", 1, 0))

        cust_df

        # 참고 포스팅
        http://rfriend.tistory.com/38

    4. IF_ELSE 2020.06.03 15:32  댓글주소  수정/삭제  댓글쓰기

      안녕하세요. 질문이 있어서 글 남깁니다.

      Suppose that the numerical vector a (a>0) is of length 1 and the numerical vector x
      is of length equal to or larger than 1. Write an R statement using the function
      ifelse to return values elementwisely as
      (i) x[i] if |x[i]| < a, (ii) a if x[i] >= a and (iii) -a if x[i] <= -a

      ##method1
      a <- 3
      x <- c(1,2,3,-4,5)

      for(i in seq_along(x)) {
      ifelse(abs(x[i])<a,x[i],if(x[i]>=a){
      a
      } else if(x[i]<=-a){
      -a
      })
      }

      ##method2
      for(i in seq_along(x)) {
      ifelse(abs(x[i])<a,x[i],
      ifelse(x[i]>=a,a,if(x[i]<=-a) -a)}

      뭔가 계속 이렇게 코드를 짜본다고 짜봤는데 원하는 값인 [1] 1 2 3 -3 3 가 안 나옵니다...ㅠㅠ

      혹시 도움 주실 수 있을까요??

      • R Friend Rfriend 2020.06.03 17:38 신고  댓글주소  수정/삭제

        안녕하세요.
        아래 코드 참고하시기 바랍니다.

        a <- 3
        x <- c(1, 2, 3, -4, 5)

        for (i in seq_along(x)){
        if (abs(x[i]) < a){
        print(x[i])
        } else if (x[i] >= a) {
        print(a)
        } else if (x[i] <= -a) {
        print(-a)
        } else {
        print(999)
        }
        }

      • IF_ELSE 2020.06.03 18:57  댓글주소  수정/삭제

        와.. 도저히 제 머리로는 생각할 수 없었던 코드인 거 같습니다..ㅠ 감사합니다!

        혹시 제가 짰던 것 처럼 ifelse를 사용했었을 때는 뭐가 문제였는지를 여쭤봐도 괜찮을까요?

        그리고 마지막에 print(999)가 뭔지도 여쭤보고 싶습니다.ㅠㅠ 죄송합니다!

      • R Friend Rfriend 2020.06.03 19:04 신고  댓글주소  수정/삭제

        혹시 위의 3개 조건에 해당안되는 원소값이 있으면 999 프린트 하라는 건데요, 마지막 999는 없애는게 낫겠네요.

        ifelse() 는 true일때와 false일때의 두가지 조건에 대한 값만 반환합니다. (포스팅 중간 참고) 그래서 조건이 많으면 코두가 깊어져서 가독성이 좀 떨어질수 있습니다.

    5. IF_ELSE 2020.06.03 19:57  댓글주소  수정/삭제  댓글쓰기

      정말 감사합니다!!

      마지막으로 결과값들을 [1] 1 2 3 -3 3 이런식으로 도출할 수는 없는건가요??

      값들이
      [1] 1
      [1] 2
      ... 이런식으로 나와서요!

    R이 통계분석 툴이자 그래픽을 위한 훌륭한 툴이면서도, 동시에 프로그래밍 언어(programming language)로서도 매우 훌륭하답니다.  반복적인 작업(Loop process)을 해야 하는 경우나, 분석가가 알고리즘을 만들어서 자동화할 수 있는 사용자 정의 함수(User defined function) 를 잘 사용한다면 소위 말하는 시간 잡아먹는 노가다를 컴퓨터에게 대신 시킬 수 있게 됩니다. 

     

    손발이 편하고 싶고, 귀한 시간을 아끼고 싶다면 R 프로그래밍에 대해 익혀두는게 유용할 것입니다.  게다가, R이 데이터 변환/처리/분석/그래프 까지 두루 섭렵하고 있다보니 "데이터 기반의 프로그래밍"이 필요한 일이라면 R이 제격이라고 하겠습니다.

     

    이번 포스팅에서는 for()와 while() 함수를 사용하여 반복 연산 프로그래밍 (Loop process programming) 하는 방법을 몇 개 예를 들어 소개하겠습니다.

     

     

    [ Loop Process Diagram ]

     

     

     

     

    (1) y= 10 + 5*x 함수에 x를 1부터 10까지 1씩 더해가면서 연산하고 y값을 순차적으로 프린트

         : for (var in seq) {expression}

     

    > # x 1:10, y = 10 + 5*x
    > for ( x in 1:10) {
    +   y = 10 + 5*x
    +   print(y)
    + }
    [1] 15
    [1] 20
    [1] 25
    [1] 30
    [1] 35
    [1] 40
    [1] 45
    [1] 50
    [1] 55
    [1] 60 

     

     

    (2) 1~10까지의 1씩 늘려가면서 누적합 구하고, 순차적으로 프린트하기

        : for (var in seq) {expression}

     

     
    > # 1~10까지 누적합 구하기 (cummulative sum by for) : for (var in seq) { expression }
    > y <- 0
    > for(i in 1:10) {
    +      y = y + i
    +      cat("cummulative summation from 0 to ", i, " is ", y, "\n", sep="")
    +    }
    cummulative summation from 0 to 1 is 1
    cummulative summation from 0 to 2 is 3
    cummulative summation from 0 to 3 is 6
    cummulative summation from 0 to 4 is 10
    cummulative summation from 0 to 5 is 15
    cummulative summation from 0 to 6 is 21
    cummulative summation from 0 to 7 is 28
    cummulative summation from 0 to 8 is 36
    cummulative summation from 0 to 9 is 45
    cummulative summation from 0 to 10 is 55
     

     

    참고로, cat 은 텍스트를 받아다가 콘솔에 프린트해주는 기능을 합니다.

    "\n" 은 줄바꿈 설정하는 파라미터입니다.

    sep="" 는 cat() 함수 안에 큰따옴표로 들어가 있는 텍스트 문자열 혹은 'i', 'z' 객체를 연결할 때 구분자를 지정해주는 것입니다. sep="" 이므로 아무것도 없이 그냥 붙여서 연결시키라는 뜻이구요, 만약 sep="__" 라고 under-bar 2개로 지정해주면 첫번째 줄이

    cummulative summation from 0 to __1__ is __1

    처럼 프린트 되었을 것입니다.

     

     

     

    (3) 1~10까지의 1씩 늘려가면서 누적합 구하고, 순차적으로 프린트하기

        : while (condition) {expression}

     

    while() 문은 조건을 걸고 싶거나 반복회수를 미리 파악하기 어려운 경우에 사용하면 유용합니다.

     

     
    > # 1~10까지 누적합 구하기 (cummlative sum by while) : while(condition) { expression }
    > z <- 0
    > i <- 1
    > while( i <= 10) {
    +      z = z + i
    +      cat("cummulative summation from 0 to ", i, " is ", z, "\n", sep="") 
    +      i = i + 1
    +    }
    cummulative summation from 0 to 1 is 1
    cummulative summation from 0 to 2 is 3
    cummulative summation from 0 to 3 is 6
    cummulative summation from 0 to 4 is 10
    cummulative summation from 0 to 5 is 15
    cummulative summation from 0 to 6 is 21
    cummulative summation from 0 to 7 is 28
    cummulative summation from 0 to 8 is 36
    cummulative summation from 0 to 9 is 45
    cummulative summation from 0 to 10 is 55
     

     

     

     


     

     

    예를 들어, 1부터 시작해서 1씩 늘려가면서 3을 더해가는 것(y = y + 3)을 반복하는데, 단 5 이하일 때까지만 반복시키는 조건이 있을 때,

     - while(condition)

     - while(TRUE/FALSE) { if () break }

     - repeat { if () break }

    의 3가지 방법을 알아보겠습니다.  아래의 (4) ~ (6)번 프로그래밍 예제는 로직과 결과가 동일합니다.

     

    (4) while(condition)

     

    > # while(condition) => stop
    > i <- 1
    > while( i <= 5 ) {
    +   i <- i+3
    + }
    > 
    > i
    [1] 7 

     

     

     

    (5) while(TRUE/FALSE) { if () break }

     

    > # while(TRUE/FALSE) { if () break } => stop
    > j <- 1
    > while(TRUE) {
    +   j <- j+3
    +   if (j > 5) break
    + }
    > 
    > j
    [1] 7

     

    처음에 j <- 1로 할당되었습니다. 

    그 다음에 while() 문으로 넘어가서요, j <- j+3 이므로 j <- 1+3 가 되어서 j에 4가 새로 할당(덮어쓰기)이 되었습니다.  if (j > 5) break 인데요, 여기서 j는 4이므로 if (j > 5) 조건에서 FALSE 가 됩니다. 따라서 break하지 않고 loop 를 계속 돌게 됩니다(not break, but continue loop). 

    그럼 다시 j <- j+3 으로 돌아가서 다시 연산을 수행합니다. 방금 전 연산에서 j가 4로 재할당 되었었지요? 그러므로 j+3 = 4+3 = 7로서 j에 7이 재할당 (덮어쓰기) 됩니다.

    if (j > 5) 조건에서 if (7 > 5) 로서 TRUE 가 되었으므로 break 하게 됩니다.

    j 를 프린트해보면 '7'이 됩니다.

     

     

     

    (6) repeat { if () break }

     

    > # repeat { if () break } => stop > k <- 1 > repeat { + k <- k+3 + if (k > 5) break + } > > k [1] 7

     

     

    위의 (5)번, (6)번 예에서 보면 while 문에는 TRUE/FALSE 의 불리언 상태값이 있습니다만, repeat 문에는 불리언 상태값 없이 break 를 사용해서 조건을 만족하면 반복을 중지시키는 차이점이 있습니다.

     

     

     


     

    아래의 프로그램 예는 repeat 함수를 이용해서 factorial(i) 값이 1,000,000,000,000 보다 작을 때까지는 계산 순차적으로 1씩 i를 증가시켜가면서 계산을 하고 프린트를 하다가, 1조보다 커지면 stop하라는 명령문입니다.

     

     
    > i <- 1
    > repeat {
    +   factorial_value <- factorial(i)
    +   cat("factorial(", i, ") = ", factorial_value, "\n", sep="")
    +   if (factorial_value > 1000000000000) break
    +   i <- i+1
    + }
    factorial(1) = 1
    factorial(2) = 2
    factorial(3) = 6
    factorial(4) = 24
    factorial(5) = 120
    factorial(6) = 720
    factorial(7) = 5040
    factorial(8) = 40320
    factorial(9) = 362880
    factorial(10) = 3628800
    factorial(11) = 39916800
    factorial(12) = 479001600
    factorial(13) = 6227020800
    factorial(14) = 87178291200
    factorial(15) = 1.307674e+12

     

     

     

     

    factorial(i) 값이 '0'이 100개 붙은 값(우리나라말로 이걸 명칭하는 단위가 없죠? 어마무시 큰 수? ^^')보다 작으면 계속 i 값을 1씩 증가시키면서 계산하다가, '0'이 100개 붙은 값보다 커지면 stop 하라는 명령문은 아래와 같습니다.

     

    > i <- 1
    > repeat {
    +   factorial_value <- factorial(i)
    +   cat("factorial(", i, ") = ", factorial_value, "\n", sep="")
    +   if (factorial_value > 1e+100) break
    +   i <- i+1
    + }
    factorial(1) = 1
    factorial(2) = 2
    factorial(3) = 6
    factorial(4) = 24
    factorial(5) = 120
    factorial(6) = 720
    factorial(7) = 5040
    factorial(8) = 40320
    factorial(9) = 362880
    factorial(10) = 3628800
    factorial(11) = 39916800
    factorial(12) = 479001600
    factorial(13) = 6227020800
    factorial(14) = 87178291200
    factorial(15) = 1.307674e+12
    factorial(16) = 2.092279e+13
    factorial(17) = 3.556874e+14
    factorial(18) = 6.402374e+15
    factorial(19) = 1.216451e+17
    factorial(20) = 2.432902e+18
    factorial(21) = 5.109094e+19
    factorial(22) = 1.124001e+21
    factorial(23) = 2.585202e+22
    factorial(24) = 6.204484e+23
    factorial(25) = 1.551121e+25
    factorial(26) = 4.032915e+26
    factorial(27) = 1.088887e+28
    factorial(28) = 3.048883e+29
    factorial(29) = 8.841762e+30
    factorial(30) = 2.652529e+32
    factorial(31) = 8.222839e+33
    factorial(32) = 2.631308e+35
    factorial(33) = 8.683318e+36
    factorial(34) = 2.952328e+38
    factorial(35) = 1.033315e+40
    factorial(36) = 3.719933e+41
    factorial(37) = 1.376375e+43
    factorial(38) = 5.230226e+44
    factorial(39) = 2.039788e+46
    factorial(40) = 8.159153e+47
    factorial(41) = 3.345253e+49
    factorial(42) = 1.405006e+51
    factorial(43) = 6.041526e+52
    factorial(44) = 2.658272e+54
    factorial(45) = 1.196222e+56
    factorial(46) = 5.502622e+57
    factorial(47) = 2.586232e+59
    factorial(48) = 1.241392e+61
    factorial(49) = 6.082819e+62
    factorial(50) = 3.041409e+64
    factorial(51) = 1.551119e+66
    factorial(52) = 8.065818e+67
    factorial(53) = 4.274883e+69
    factorial(54) = 2.308437e+71
    factorial(55) = 1.26964e+73
    factorial(56) = 7.109986e+74
    factorial(57) = 4.052692e+76
    factorial(58) = 2.350561e+78
    factorial(59) = 1.386831e+80
    factorial(60) = 8.320987e+81
    factorial(61) = 5.075802e+83
    factorial(62) = 3.146997e+85
    factorial(63) = 1.982608e+87
    factorial(64) = 1.268869e+89
    factorial(65) = 8.247651e+90
    factorial(66) = 5.443449e+92
    factorial(67) = 3.647111e+94
    factorial(68) = 2.480036e+96
    factorial(69) = 1.711225e+98
    factorial(70) = 1.197857e+100

     

     

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

     

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

     

     

    Posted by R Friend Rfriend

    댓글을 달아 주세요

    1. kjh 2016.09.16 17:14  댓글주소  수정/삭제  댓글쓰기

      한 데이터셋에 있는 각 열별 NA 개수를 출력하는 반복문을 만들려고 하는데요
      for(i in 1:length(CLAIM)){
      sum(is.na(CLAIM[i]))
      }

      저는 CLAIM이라는 데이터셋을 사용했는데..
      R Studio가 아무것도 안해줍니다 ㅠㅠ
      제 명령을 씹어요..
      length(CLAIM)도 제대로 동작하고
      sum(is.na(CLAIM[3]) 이런식으로 숫자를 넣어봐도 제대로 동작하는걸 확인했는데
      for는 먹통이네요.. 왜그럴까요? 출력을 안해줘요 오류도 안뜨구요.

      • R Friend Rfriend 2016.09.16 17:52 신고  댓글주소  수정/삭제

        kjh님,
        원하시는 실행은 아래처럼 colSums(is.na(dataframe)) 함수를 사용하시면 됩니다.

        colSums(is.na(CLAIM))


        루프문에 칼럼 이름별로 결측값 개수를 개별 변수이름별로 할당하려면 아래 링크 assign()함수 참고하세요. 제가 시골 내려와있는데 컴퓨터를 사용할수 없어서 길게는 못쓰겠네요.

        assign()함수
        http://rfriend.tistory.com/m/108

    2. 2017.03.18 21:26  댓글주소  수정/삭제  댓글쓰기

      비밀댓글입니다

      • R Friend Rfriend 2017.03.18 21:48 신고  댓글주소  수정/삭제

        안녕하세요.

        (1) cat 은 텍스트를 받아다가 콘솔에 프린트해주는 기능을 합니다.

        "\n" 은 줄바꿈 설정하는 파라미터입니다.

        sep="" 는 cat() 함수 안에 큰따옴표로 들어가 있는 텍스트 문자열 혹은 'i', 'z' 객체를 연결할 때 구분자를 지정해주는 것입니다. sep="" 이므로 아무것도 없이 그냥 붙여서 연결시키라는 뜻이구요, 만약 sep="__" 라고 under-bar 2개로 지정해주면 첫번째 줄이

        cummulative summation from 0 to __1__ is __1

        처럼 프린트 되었을 것입니다.

        (2) while() 문은 TRUE/FALSE 불리언 조건이 만족할 때까지 반복작업을 수행하게 됩니다.

        따라서 (5) 번 예제를 예로 들어 설명해보면요,

        처음에 j <- 1로 할당되었습니다.

        그 다음에 while() 문으로 넘어가서요, j <- j+3 이므로 j <- 1+3 가 되어서 j에 4가 새로 할당(덮어쓰기)이 되었습니다. if (j > 5) break 인데요, 여기서 j는 4이므로 if (j > 5) 조건에서 FALSE 가 됩니다. 따라서 break하지 않고 loop 를 계속 돌게 됩니다(not break, but continue loop).

        그럼 다시 j <- j+3 으로 돌아가서 다시 연산을 수행합니다. 방금 전 연산에서 j가 4로 재할당 되었었지요? 그러므로 j+3 = 4+3 = 7로서 j에 7이 재할당 (덮어쓰기) 됩니다.

        if (j > 5) 조건에서 if (7 > 5) 로서 TRUE 가 되었으므로 break 하게 됩니다.

        j 를 프린트해보면 '7'이 됩니다.


        블로그 글 좋게 봐주셔서 감사합니다. ^^

    3. 2017.03.25 16:34  댓글주소  수정/삭제  댓글쓰기

      비밀댓글입니다

      • R Friend Rfriend 2017.03.27 19:51 신고  댓글주소  수정/삭제

        벡터끼리의 논리 연산의 경우 loop 문을 안써도 알아서 순환하면서 벡터 내 원소끼리 비교를 해서 TRUE, FALSE를 반환해 줍니다. 가령,

        (1) 두 벡터의 원소의 개수가 같을 경우 논리 연산

        a <- c(1, 2, 3, 4, 5)
        b <- c(0, -1, 4, 4, 10)

        a >= b

        TRUE TRUE FALSE TRUE FALSE
        를 반환합니다.

        (2) 두 벡터의 원소 개수가 다를 경우 : 원소 개수가 작은 쪽이 순서대로 broadcasting 을 해서 알아서 짝을 맞추어서 논리 연산을 수행 (단, 벡터의 원소 개수(길이)가 서로 다르다고 경고 메시지가 빨간 색으로 뜸)

        a <- c(1, 2, 3, 4, 5)
        c <- c(-5, 4, 1)

        a >= c

        TRUE FALSE TRUE TRUE TRUE

    4. 폴짝이 2019.08.10 21:41  댓글주소  수정/삭제  댓글쓰기

      R 데이터 분석을 하는데
      양적변수와 양적변수를 비교하려는 그래프를 그리려는데 변수가 많은데.. 어떻게 표현해야하는지 모르겠습니다,

      • R Friend Rfriend 2019.08.10 23:00 신고  댓글주소  수정/삭제

        정확한 요건이 무엇인지 몰라 좀 애매하긴 한데요, 아래의 클리브랜드 점 그래프 한번 참고해보세요.

        https://rfriend.tistory.com/75

        ggplot2의 facet_grid 옵션도 참고하세요.

        for loop 이나 혹은 사용자 정의함수도 한번 고려해볼 수 있겠구요.

        R Shiny로 interactive plot 도 생각해볼 수 있겠네요.

    5. hsdonow 2020.03.25 23:47  댓글주소  수정/삭제  댓글쓰기

      안녕하세요.
      혹시 R에서도 uniquecount 같은 함수가 있을까요??

      어떤 테이블에 a,b라는 컬럼이 있을 때
      a 컬럼의 value별 b컬럼의 특정 value에 대한 uniquecount를 구하고 싶습니다.

      a || b || unicount(b==1)
      x 1 1
      x 1 1
      x 2 1
      y 1 1
      y 2 1
      z 2 0
      z 3 0
      z 3 0

      • R Friend Rfriend 2020.03.26 00:07 신고  댓글주소  수정/삭제

        안녕하세요.

        아래의 코드를 참고해서 한번 수행해보시고 원하시는 결과인지 확인해보세요. dplyr 패키지의 filter() 와 group_by() & summarise(n=n()), 혹은 count() 함수를 사용하였습니다.

        * dplyr 패키지를 사용해서 그룹별 행의 개수 세기 참고 포스팅: https://rfriend.tistory.com/240

        a <- c("x", "x", "x", "y", "y", "z", "z", "z")
        b <- c(1, 1, 1, 1, 1, 0, 0, 0)

        df <- data.frame(a, b)
        df

        library(dplyr)
        # 방법 1
        df %>%
        filter(b == 1) %>%
        group_by(a) %>%
        summarise(n = n())

        # 방법 2
        df %>%
        filter(b == 1) %>%
        count(a)

    6. 김지훈 2020.06.10 23:38  댓글주소  수정/삭제  댓글쓰기

      안녕하세요. 선생님

      우선 항상 좋은 글, 친절한 답변 남겨주셔서 감사합니다. 지난번에 글 쓴게 삭제되어 여기에 감사 인사 드립니다.

      방법1.
      z <- c() #외부변수 지정
      for(x in 1:10){
      y = 10 +5*x
      z[x] <- y
      }
      z # [1] 15 20 25 30 35 40 45 50 55 60

      방법2.
      for(x in 1:10){
      y = 10 +5*x
      z <- c() #내부변수 지정
      z[x] <- y
      }
      z #[1] NA NA NA NA NA NA NA NA NA 60

      혹시 이렇게 빈 벡터를 작성할 때 외부지정과 내부지정의 차이가 발생하는 이유가 뭔지 여쭤봐도 괜찮을까요?

      • R Friend Rfriend 2020.06.10 23:50 신고  댓글주소  수정/삭제

        안녕하세요 김지훈님,

        빈 벡터 z를 외부에 지정하면 처음에 딱 한번만 빈 벡터가 생성이 되고, 그 다음부터는 for loop을 돌면서 z벡터의 x의 위치에 y값을 assign 해줍니다.

        반면에 빈 벡터 z를 for loop의 내부에 만들게 되면 for loop을 도는 동안 계속해서 값이 다시 초기화(c()) 되어서 빈 벡터로 바뀌게 되고, 이렇게 새로 비어있는 벡터 z에 가장 최신의 y값만 x의 위치에 assign 하게 됩니다. 물론 이 값도 for loop을 한번 더 돌게 되면 다시 빈 벡터로 초기화되고, 다시 가장 최신의 y값만 마지막 위치 x에 assign 되게 됩니다.
        아래에 '방법2'의 for loop의 각 단계별로 output을 print 하도록 한 결과인데요, 이것을 유심히 살펴보시면 좀더 이해하기 쉬울 듯 합니다.

        > for (x in 1:10){
        + y <- 10 + 5*x
        + print(paste0('x: ', x, ', y: ', y))
        + z <- c()
        + z[x] <- y
        + print(paste0('z: ', z))
        + }
        [1] "x: 1, y: 15"
        [1] "z: 15"
        [1] "x: 2, y: 20"
        [1] "z: NA" "z: 20"
        [1] "x: 3, y: 25"
        [1] "z: NA" "z: NA" "z: 25"
        [1] "x: 4, y: 30"
        [1] "z: NA" "z: NA" "z: NA" "z: 30"
        [1] "x: 5, y: 35"
        [1] "z: NA" "z: NA" "z: NA" "z: NA" "z: 35"
        [1] "x: 6, y: 40"
        [1] "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: 40"
        [1] "x: 7, y: 45"
        [1] "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: 45"
        [1] "x: 8, y: 50"
        [1] "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: 50"
        [1] "x: 9, y: 55"
        [1] "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: 55"
        [1] "x: 10, y: 60"
        [1] "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: NA" "z: 60"

    7. 김지훈 2020.06.11 22:27  댓글주소  수정/삭제  댓글쓰기

      항상 바쁘실텐데 감사합니다. 이해가 너무 잘 됩니다.

    8. JH 2021.01.14 09:59  댓글주소  수정/삭제  댓글쓰기

      data에 있는 var1~var30의 correlation을 보려고 하는데,
      LOOP가 제대로 작동하지 않습니다.
      도움을 주실 수 있으신가요?

      for (i in 1:30) {
      for (j in 1:30) {
      tempvar1 = get(paste("data$var",i,sep=""))
      tempvar2 = get(paste("data$var",j,sep=""))
      tempname = paste("ccf",i,sep="")
      tempname = ccf(tempvar1, tempvar2, lag.max = 36, type = "correlation")
      }
      }

      • R Friend Rfriend 2021.01.14 10:15 신고  댓글주소  수정/삭제

        아래의 상관계수에 대한 포스팅의 하단 부분에 '여러개 숫자형 변수간 상관계수를 세로로 긴 형태 (Long format)로 저장하기' 방법에 대한 R 코드를 추가했습니다. 참고하시기 바랍니다.

        https://rfriend.tistory.com/126

    그동안 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 Rfriend

    댓글을 달아 주세요

    이번 포스팅에서는 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 Rfriend

    댓글을 달아 주세요

    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 Rfriend

    댓글을 달아 주세요

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

      비밀댓글입니다

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

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

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

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

      비밀댓글입니다

      • R Friend Rfriend 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 Rfriend

    댓글을 달아 주세요

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

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

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

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

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

      • R Friend Rfriend 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 Rfriend

    댓글을 달아 주세요

    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 Rfriend 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축으로 중첩되는 것을 그리 잘 해결하지는 못해보이네요. ^^;;;

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

      • HG 2020.12.30 22:18  댓글주소  수정/삭제

        geom_text(aes(label=Model),check_overlap = TRUE, vjust=1,colour="grey40",size=3)
        로 하면 해결되요

      • R Friend Rfriend 2020.12.30 22:22 신고  댓글주소  수정/삭제

        안녕하세요 HG님,
        check_overlap=TRUE 옵션이 있었군요. 덕분에 저도 하나 배웠습니다.
        댓글 감사합니다. ^^b