ggplot2 패키지는 시각화를 대표하는 패키지로써, R의 가장 큰 자랑이기도 합니다. 그러나 기본 패키지 만으로는 모든 데이터를 표현하기 힘들기에, 이를 보완하기 위한 각종 확장 패키지들이 존재합니다. 이러한 확장 패키지를 잘 사용한다면 더욱 다채로운 시각화 표현이 가능합니다.
library(stringr) library(dplyr) KOR_ticker = read.csv('https://raw.githubusercontent.com/hyunyulhenry/quant_cookbook/master/data/KOR_ticker.csv', row.names = 1, stringsAsFactors = FALSE) KOR_sector = read.csv('https://raw.githubusercontent.com/hyunyulhenry/quant_cookbook/master/data/KOR_sector.csv', row.names = 1, stringsAsFactors = FALSE) KOR_ticker$'종목코드' = str_pad(KOR_ticker$'종목코드', 6,'left', 0) KOR_sector$'CMP_CD' = str_pad(KOR_sector$'CMP_CD', 6, 'left', 0) data_market = left_join(KOR_ticker, KOR_sector, by = c('종목코드' = 'CMP_CD', '종목명' = 'CMP_KOR')) data_market = data_market %>% rename(`시가총액` = `시가총액.원.`) data_market = data_market %>% mutate(`PBR` = as.numeric(PBR), `PER` = as.numeric(PER), `ROE` = PBR / PER, `ROE` = round(ROE, 4), `size` = ifelse(`시가총액` >= median(`시가총액`, na.rm = TRUE), 'big', 'small') )
먼저 필요한 데이터를 불러온 후 클렌징 하도록 하겠습니다.
퀀트 투자 쿡북의 책 내용을 그대로 따오도록 합니다.
https://hyunyulhenry.github.io/quant_cookbook/section-38.html#section-39
8월말에 종이책으로 발간됩니다.
한권씩 매수매수..... 플리즈...
1. corrplot
corrplot은 상관관계 행렬을 시각화해주는 확장 패키지로써, 상관관계의 강도를 더욱 이해하기 쉽게 만들어 줍니다.
data_market %>% select(PER, PBR, ROE) %>% mutate(PER = min_rank(PER), PBR = min_rank(PBR), ROE = min_rank(desc(ROE))) %>% cor(use = 'complete.obs') PER PBR ROE PER 1.0000000 0.4617038 0.6097884 PBR 0.4617038 1.0000000 -0.3525682 ROE 0.6097884 -0.3525682 1.0000000
종목의 PER, PBR, ROE의 랭크를 구한 후 (ROE의 경우 내림차순) 상관관계를 구해주었습니다. 단순히 숫자로 표현되어 한눈에 확인하기 힘듭니다.
library(corrplot) data_market %>% select(PER, PBR, ROE) %>% mutate(PER = min_rank(PER), PBR = min_rank(PBR), ROE = min_rank(desc(ROE))) %>% cor(use = 'complete.obs') %>% corrplot(method = 'circle', addCoef.col = 'white', number.cex = 0.7)
상관관계의 부호가 색깔, 크기가 원의 지름으로 표현되어 훨씬 이해하기 쉽습니다.
method를 통해 그림 모양을 변경할 수도 있으며, 각종 인자를 변경해가며 원하는 그림을 나타낼 수 있습니다. 자세한 사용법은 아래 링크를 참조하시기 바랍니다.
https://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html
2. waffle
waffle 패키지는 와플 차트를 그려줌으로써, 각 데이터의 비율을 이해하기 쉽게 합니다.
library(waffle) library(dplyr) library(magrittr) df = data_market %>% select(SEC_NM_KOR) %>% filter(!is.na(SEC_NM_KOR)) %>% table() %>% sort(decreasing = TRUE) df . IT 경기관련소비재 산업재 건강관리 소재 574 393 332 226 216 필수소비재 금융 에너지 유틸리티 커뮤니케이션서비스 96 78 23 19 7
먼저 table() 함수를 이용해 각 섹터별 구성종목수를 확인해보도록 합니다.
df %>% divide_by(5) %>% waffle(color = rainbow(10), size = 1, legend_pos = "bottom")
스케일링을 위해 divide_by()를 통해 5로 나눠준 다음, waffle()을 통해 와플차트를 표현합니다. 각 섹터의 갯수만큼 정사각형으로 표현되어 비율의 차이를 한눈에 확인할 수 있습니다.
https://github.com/hrbrmstr/waffle/tree/cran
3. treemapify
주식을 하시는 분이라면 이런 그림을 많이 보셨을 겁니다. treemap을 통해 시가총액을 사각형으로 표현하였으며, 그 내부에 각 종목명 및 수익률이 표현되어 있습니다.
R의 treemapify 패키지를 사용한다면 treemap을 매우 쉽게 그릴 수 있습니다.
data_market %>% select(시가총액, SEC_NM_KOR, PBR) %>% filter(!is.na(SEC_NM_KOR)) %>% mutate(시총비 = 시가총액 / sum(시가총액), 시총비 = round(시총비, 3)) %>% group_by(SEC_NM_KOR) %>% summarize(시총비 = sum(시총비), PBR = median(PBR, na.rm = TRUE)) %>% ggplot(aes(area = 시총비, fill = SEC_NM_KOR, label = paste(SEC_NM_KOR, PBR, sep = '\n\n'))) + geom_treemap() + geom_treemap_text(place = 'centre') + theme(legend.position = "none")
먼저 mutate를 통해 시총비를 구해준 후, 섹터 별 시총비와 PBR의 median 값을 구해줍니다.
그 후 ggplot을 통해 area(영역)은 시총비, fill(영역색)은 색터 이름, 라벨은 paste 함수를 통해 섹터명과 PBR을 합쳐주며, \n을 통해 줄바꿈을 해줍니다. 그 후 treemapify 패키지의 geom_treemap() 함수를 이용해주면 treemap이 표현됩니다.
각 사각형의 크기는 시총비를 나타내며, IT와 경기관련소비재가 국내 시총의 절반 정도를 차지함이 보입니다. 반면 건강관리는 시총비중이 그렇게 크지 않음에도 불구하고 PBR이 2.59로 매우 높음이 보입니다.
https://wilkox.org/treemapify/
4. ggrepel
ggplot을 이용해 그림 위에 텍스트를 표현할 경우 잘 보이지 않을 때가 있습니다. ggrepel은 이러한 텍스트를 보기 쉽게 표현해주는 확장 패키지입니다.
library(ggrepel) library(gridExtra) p1 = data_market %>% filter(!is.na(SEC_NM_KOR)) %>% group_by(SEC_NM_KOR) %>% summarize(ROE_sector = median(ROE, na.rm = TRUE), PBR_sector = median(PBR, na.rm = TRUE)) %>% ggplot(aes(x = ROE_sector, y = PBR_sector, color = SEC_NM_KOR, label = SEC_NM_KOR)) + geom_point() + geom_text(color = 'black', size = 3, vjust = 1.3) + theme(legend.position = "none") p1
각 섹터의 ROE와 PBR의 median값을 점으로 나타낸 후, geom_text() 함수를 통해 텍스트를 표현했습니다. 그러나 산업재, 필수소비재, 에너지, 경기관련소비재의 경우 글씨들이 몰려있어 구분하기가 쉽지 않습니다.
p2 = data_market %>% filter(!is.na(SEC_NM_KOR)) %>% group_by(SEC_NM_KOR) %>% summarize(ROE_sector = median(ROE, na.rm = TRUE), PBR_sector = median(PBR, na.rm = TRUE)) %>% ggplot(aes(x = ROE_sector, y = PBR_sector)) + geom_point() + geom_label_repel( aes(x = ROE_sector, y = PBR_sector, label = SEC_NM_KOR, color = SEC_NM_KOR) ) + theme(legend.position = "none") p2
동일한 내용이지만 ggrepel 패키지의 geom_label_repel() 함수를 이용할 경우 훨씬 구분하기가 쉽게 표현됩니다.
grid.arrange(p1, p2, ncol = 1)
gridExtra 패키지의 grid.arrange() 함수는 여러개의 ggplot 그림을 하나의 화면에 출력해줍니다. ggrepel 패키지를 이용하는 것이 내용을 확인하기 훨씬 쉽습니다.
https://cran.r-project.org/web/packages/ggrepel/vignettes/ggrepel.html
5. ggradar
레이더 혹은 스파이더 차트는 게임에 많이 나오는 차트입니다. 흔히 능력치를 보기쉽게 나타내주는 그래프입니다.
ggradar 패키지의 경우 CRAN의 공식 패키지가 아니므로 github를 통해 다운로드 받아야 됩니다.
devtools::install_github("ricardo-bion/ggradar", dependencies = TRUE) library(ggradar) library(scale)
library(dplyr)data_market %>% filter(!is.na(SEC_NM_KOR)) %>% mutate(tile_size = ntile(desc(시가총액), 5)) %>% group_by(tile_size) %>% summarize(ROE = median(ROE, na.rm = TRUE), PBR = median(PBR, na.rm = TRUE), PER = median(PER, na.rm = TRUE), DY = median(배당수익률, na.rm = TRUE)) %>% mutate_at(vars(-tile_size), rescale) %>% ggradar() + theme(legend.position = 'bottom', legend.title = element_blank())
먼저 ntile() 함수를 이용해 시가총액을 5개 분위 (내림차순)으로 나눠주도록 합니다. 그 후 각 그룹별 ROE, PBR, PER, DY를 구해준 후, 분위수명(tile_size)를 제외한 컬럼을 scale 패키지의 rescale() 함수를 이용해 0에서 1 값이 되도록 표준화 해줍니다.
그 후 ggradar() 함수를 입려해주면 레이더 차트가 자동으로 생성됩니다.
분위수가 높을 수록, 즉 시가총액이 클수록 ROE와 PBR은 높은 Quality 주식이 많고, 분위수가 낮을수록, 즉 시가총액이 작을수록 ROE와 PBR이 낮은 Junk 주식이 많음이 보입니다.
이 외에도 ggplot의 다양한 확장 패키지는 아래의 사이트에서 확인할 수 있습니다.
http://www.ggplot2-exts.org/gallery/
댓글 없음:
댓글 쓰기