ggplot2 를 사용하여 100% 기준 누적막대그래프 그리기

일반적인 막대그래프는 여러가지 값을 하나의 막대그래프에 누적해서 쌓아서 그 구성내용을 볼 수 있는 그래프이다. 아래 그림1 처럼 특정 기준으로 그 구성비율을 알기는 쉽지만 그 총계는 다르다보니, 정확하게 막대별로 비율의 비교는 하기 어렵다.

일반적인 누적막대그래프

그래서 총계가 다르더라도 100% 기준으로 그 안의 구성비를 보여주는 그래프가 아래 그림2와 같은 100%기준 누적막대그래프이다. 동일한 높이로 재구성되다보니 어느정도의 비율로 구성되어 있는지 비교하기 쉬워진다.

100%기준 누적막대그래프

데이터 만들기

이번에 사용한 데이터는 한국은행의 정기예금 기간별 말잔 통계데이터를 활용하기로 했다. 한국은행 경제통계시스템에 있는 데이터를 받아다가 이리저리 가공해서 그래프를 그리기 적합한 아래의 레이아웃으로 데이터를 만들었다. 만드는 과정이 꽤나 길긴한데 이걸 정리하는 포스트는 아니어서 생략하고, 여기를 클릭해서 파일을 다운로드 받는다. 그리고 readr 패키지의 read_csv 함수로 파일을 읽어 사용하면 된다.

readr::read_csv("./2022/20221129/data.csv")

# A tibble: 8 × 6
      x date         ord   value  rate class            
  <int> <date>     <dbl>   <dbl> <dbl> <chr>            
1     1 2020-09-01     4  45487.   6.2 2년이상          
2     1 2020-09-01     3 445958.  60.4 1년이상 2년미만  
3     1 2020-09-01     2 163153.  22.1 6개월이상 1년미만
4     1 2020-09-01     1  84281.  11.4 6개월미만        
5     2 2022-09-01     4  43337.   4.8 2년이상          
6     2 2022-09-01     3 491848.  54.1 1년이상 2년미만  
7     2 2022-09-01     2 181745.  20   6개월이상 1년미만
8     2 2022-09-01     1 192510.  21.2 6개월미만 

100%기준 누적막대그래프 그리기

처음에는 그냥 누적막대그래프를 그려준다. reorder 관련해서 잘 모르면 여기를 클릭해서 참고한다.

ggplot(tb5, aes(x, value, fill = reorder(class, ord))) +
  geom_col(width = 0.5)

100%기준 누적막대그래프를 그리기위한 옵션으로 position = position_fill() 을 셋팅한다. 그러면 자동으로 y축이 100%기반으로 조정된다.

ggplot(tb5, aes(x, value, fill = reorder(class, ord))) +
  geom_col(position = position_fill(),
           width = 0.5)

추가로 텍스트까지 넣어준다. 넣어줄때, 여기도 position 옵션을 셋팅해야 하는데 0.5라는 값을 넣어줘야 한다. 텍스트가 표시될 위치인데 0이 가장 아래, 1이 가장 높은 위치라고 생각하면 된다. 그래서 0.5 로 입력해서 중간위치에 텍스트를 위치시켰다.

ggplot(tb5, aes(x, value, fill = reorder(class, ord))) +
  geom_col(position = position_fill(),
           width = 0.5) +
  geom_text(aes(label = rate), 
            position = position_fill(0.5))

마지막으로 약간의 여백을 주기위해, scale_x_continuous 함수를 이용하여 공간을 조정한다.

ggplot(tb5, aes(x, value, fill = reorder(class, ord))) +
  geom_col(position = position_fill(),
           width = 0.5) +
  geom_text(aes(label = rate), 
            position = position_fill(0.5)) +
  scale_x_continuous(breaks = 1:2,
                     label = c("'20.9월", "'22.9월"),
                     expand = expansion(c(0.15, 0.15)))


더 보면 좋을 글들