[R] ggplot2 의 커널 밀도 곡선(Kernel Density Curve)의 최대 피크값 좌표구하고 수직선 추가하기
R 분석과 프로그래밍/R 그래프_시각화 2019. 10. 3. 16:12이번 포스팅에서는
(1) R ggplot2를 이용하여 커널 밀도 곡선(Kernel Density Curve)을 그리기,
(2) 커밀 밀도 곡선의 최대 피크값의 좌표 구하기
(X, Y coordinates of the peak value in kernel density curve)
(3) 커널 밀도 곡선의 최대 피크값 위치에 수직선을 추가하는 방법 (adding a vertical line at peak value in kernel density plot) 을 소개하겠습니다.
(1) R ggplot2로 커널 밀도 곡선 그리기 (Kernel Density Curve by R ggplot2) |
예제로 사용할 데이터는 MASS 패키지에 내장되어 있는 Cars93 데이터프레임입니다. 자동차의 가격(Price 변수)에 대해서 R ggplot2로 커널 밀도 곡선 (not frequency, but density) 을 그려보겠습니다.
> library(MASS) > library(ggplot2) > > ggplot(Cars93, aes(x=Price)) + + geom_density(fill = 'yellow') + + geom_line(stat = "density") + + expand_limits(y = 0) + + ggtitle("Kernel Density Curve") |
(2) 커널 밀도 곡선의 최대 피크값의 좌표 구하기 (X, Y coordinates of the peak value in kernel density curve) |
density(df$var) 함수를 사용하면 x 와 y 값의 요약통계량 (최소, Q1, 중앙값, Q3, 최대값)을 확인할 수 있습니다. y 값의 최대값(Max)은 5.025e-02 값이네요.
> density(Cars93$Price) Call: density.default(x = Cars93$Price) Data: Cars93$Price (93 obs.); Bandwidth 'bw' = 3.011 x y Min. :-1.634 Min. :1.608e-05 1st Qu.:16.508 1st Qu.:9.773e-04 Median :34.650 Median :5.329e-03 Mean :34.650 Mean :1.377e-02 3rd Qu.:52.792 3rd Qu.:2.078e-02 Max. :70.934 Max. :5.025e-02 |
이중에서 y 값 peak 값의 x 좌표를 알고 싶으므로 (a) which.max(density(Cars93$Price)$y) 로 y값의 최대 peak 값을 가지는 데이터의 index를 찾고 (127번째 데이터), 이 index를 이용해서 x 값의 좌표(16.25942)를 indexing 해올 수 있습니다.
> which.max(density(Cars93$Price)$y) [1] 127 > x_coord_of_y_max = density(Cars93$Price)$x[127] > x_coord_of_y_max [1] 16.25942
|
즉, y (Price) 최대 피크값의 좌표는 (x, y) 는 (16.25922, 0.05025) 가 되겠습니다.
(3) 커널 밀도 곡선의 최대 피크값 위치에 수직선을 추가하기 (adding a vertical line at peak value in kernel density plot) |
geom_vline() 으로 (2)번에서 구한 y 피크값의 x 좌표를 입력해주면 커널밀도곡선의 최대 피크값 위치에 수직선(vertical line)을 추가할 수 있습니다.
> ggplot(Cars93, aes(x=Price)) + + geom_density(fill = 'yellow') + + geom_line(stat = "density") + + expand_limits(y = 0) + + ggtitle("Kernel Density Curve w/ Vertical Line at Peak Point") + + geom_vline(xintercept = x_coord_of_y_max, color='blue', size=2, linetype="dotted")
|
(4) 여러개 그룹의 커널 밀도 곡선을 겹쳐 그린 경우 최대 peak 값 찾고 수직선 그리기 |
위의 예는 1개의 데이터셋에 대해 1개의 커널 밀도 곡선을 그린 후 최대 peak 값을 찾는 것이었습니다. 이제부터는 여러개의 하위 그룹으로 나뉘어진 데이터셋으로 여러개의 커널 밀도 곡선을 겹쳐서 그린 경우에 최대 peak 값을 찾고, 그 위치에 빨간색으로 수직선을 추가해보겠습니다.
예제로 Cars93 데이터프레임에서 차종(Type) 별 가격(Price)의 커널 밀도 곡선을 겹쳐서 그려보겠습니다.
> ggplot(Cars93, aes(x=Price, colour = Type)) + + geom_density(fill = NA) + + geom_line(stat = "density") + + expand_limits(y = 0) + + ggtitle("Kernel Density Curve by Car Types") |
차종(Type) 중에서 Van 의 커널 밀도 곡선이 최대 Peak 값에 해당하므로 --> 차종 중에서 Van 의 데이터만 가져와서 y 최대값과 이에 해당하는 관측치의 index 위치를 찾아보겠습니다.
> density(Cars93[Cars93$Type=='Van', ]$Price) Call: density.default(x = Cars93[Cars93$Type == "Van", ]$Price) Data: Cars93[Cars93$Type == "Van", ]$Price (9 obs.); Bandwidth 'bw' = 0.303 x y Min. :15.39 Min. :0.0000072 1st Qu.:17.45 1st Qu.:0.0040424 Median :19.50 Median :0.0495649 Mean :19.50 Mean :0.1215343 3rd Qu.:21.55 3rd Qu.:0.1807290 Max. :23.61 Max. :0.5321582 > which.max(density(Cars93[Cars93$Type=='Van', 'Price'])$y) [1] 238 > x_coord_of_y_max = density(Cars93[Cars93$Type=='Van','Price'])$x[238] > x_coord_of_y_max [1] 19.20249
|
밀도 y의 최대값(max)은 0.532 이며, 이때의 관측치의 index는 238번째 값 이고, 관측치 238번째 값의 x값의 좌표는 19.20 입니다.
따라서, 밀도 y 의 최대 peak 값의 좌표는 (x, y) = (19.20, 0.53) 이네요.
마지막으로, geom_vline() 을 사용해서 밀도 최대 peak 값에 해당하는 x=19.20 을 기준으로 빨간색 점선 수직선(vertical line)을 추가해보겠습니다.
> ggplot(Cars93, aes(x=Price, colour = Type)) + + geom_density(fill = NA) + + geom_line(stat = "density") + + expand_limits(y = 0) + + ggtitle("Kernel Density Curve w/ Vertical Line at Peak Point") + + theme_bw() + + geom_vline(xintercept = x_coord_of_y_max, color='red', size=1, linetype="dashed") |
R ggplot2로 히스토그램, 커널밀도곡선을 그리는 다양한 방법은 https://rfriend.tistory.com/67 를 참고하세요.
많은 도움이 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. ^^
'R 분석과 프로그래밍 > R 그래프_시각화' 카테고리의 다른 글
[R] 반복문 프로그램 진행 경과 막대로 나타내기 (progress bar) (1) | 2021.01.23 |
---|---|
[R] ggplot2로 bin 범위가 다른 히스토그램 그리기 (histogram with different bin width using R ggplot2) (4) | 2019.02.17 |
[R] ggplot으로 이중축 그래프 그래기 (dual y-axes plot using ggplot2) (4) | 2018.06.16 |
클리브랜드 점 그래프 (KRUG 2017.11.18 주말 퀴즈) (2) | 2017.11.18 |
[R] ggplot 그래프 크기 조정, 가로 세로 비율 조정 : coord_fixed(ratio = 2, 1, 0.5) (0) | 2017.09.09 |