사용데이터 : https://2stndard.tistory.com/68
앞선 포스트(https://2stndard.tistory.com/75)에서는 백분률을 사용한 히스토그램을 어떻게 그리는지 살펴보았다. 하지만 이 포스트에서 만들어낸 결과는 두가지 점에서 바로 사용하기가 좀 어려울 것이다.
첫 번째는 막대로 백분률을 표시는 했지만 그 정확한 값을 알수가 없다는 것이다. 막대간의 비교는 가능해 어떤 변수값이 가장 많이 분포하는 지는 알수 있지만 이는 빈도수로 표현된 히스토그램으로도 알수 있다. 따라서 정확한 백분률을 표시해 주는 것이 효과적일 것이다.
두 번째는 막대 그래프는 오름차순이나 내림차순으로 막대를 배치할 때 그 활용도가 커진다. 하지만 앞선 포스팅에서 그려진 막대 그래프의 막대는 들쭉 날쭉하다.
이를 다음과 같이 해결해 보겠다.
백분률의 표시
앞선 포스트에서 그렸던 연속형 변수에 대한 백분률 히스토그램과 이산형 변수에 대한 백분률 히스토그램에 백분률을 표현하는 방법을 구분하였고 이에 따라 사용하는 함수도 geom_histogram()
과 geom_bar()
로 구분하여 생성하였다. 백분률의 표시도 이 두 함수의 사용에 따라 달라진다.
먼저 geom_histogram()
에서 백분률을 표시하기 위해서는 stat_bin()
를 사용하여야 한다. stat_bin()
는 히스토그램을 표현하는데 중요하게 사용되는 binning에 따른 기하요소의 사용을 위한 함수이다. ggplot2
에서 데이터 값을 표현하는데 가장 흔하게 사용되는 geom_text()
는 binning을 사용하기가 어렵기 때문에 stat_bin()
를 사용하여야 한다.
df_취업률_2000 |>
ggplot() +
geom_histogram(aes(x = 취업률, y = ..count../sum(..count..))) +
stat_bin(aes(x = 취업률, y = ..count../sum(..count..),
label = scales::percent(..count../sum(..count..), accuracy = 1)),
geom = 'text', vjust = -0.5) +
scale_y_continuous(labels = scales::percent) +
labs(y = '백분률')
binning을 binwidth
로 설정한 경우는 다음과 같이 stat_bin()
에 binwidth
를 설정해 줌으로써 히스토그램을 만들수 있다.
df_취업률_2000 |>
ggplot() +
geom_histogram(aes(x = 취업률, y = ..count../sum(..count..)), binwidth = 10) +
stat_bin(aes(x = 취업률, y = ..count../sum(..count..),
label = scales::percent(..count../sum(..count..), accuracy = 1)),
geom = 'text', vjust = -0.5,
binwidth = 10) +
scale_y_continuous(labels = scales::percent) +
labs(y = '백분률')
이산형 변수에 대한 히스토그램을 그리는데 사용한 geom_bar()
는 geom_text()
를 사용함으로써 백분률을 표시할 수 있다. 이번에는 비율과 개수를 같이 표현해보도록 하겠다.
이산형 변수에 대한 히스토그램을 그리는 방법으로 ..count..
사용, after_stat()
의 사용, ..prop..
의 사용 세 가지 방법으로 설명하였는데 각각의 방법에 따라 백분률을 표현하는 방법은 다음과 같다.
## ..count..를 사용하는 방법
df_취업률_2000 |>
ggplot() +
geom_bar(aes(x = 대계열, y = ..count../sum(..count..))) +
geom_text(aes(x = 대계열, y = ..count../sum(..count..), group = 1,
label = paste0(..count.., '개(', scales::percent(..prop.., accuracy = 0.1), ')')
),
stat = 'count', vjust = -0.5
) +
scale_y_continuous(labels = scales::percent) +
labs(y = '백분률')
## after_stat()을 사용한 방법
df_취업률_2000 |>
ggplot(aes(x = 대계열, y = after_stat(count/sum(count)))) +
geom_bar() +
geom_text(aes(label = paste0(after_stat(count), '개(', scales::percent(after_stat(count/sum(count))), ')')
),
stat= "count", vjust = -0.5) +
scale_y_continuous(labels = scales::percent) +
labs(y = '백분률')
## ..prop..을 사용한 방법
df_취업률_2000 |>
ggplot() +
geom_bar(aes(x = 대계열, y = ..prop.., group = 1)) +
geom_text(aes(x = 대계열, y = ..prop.., group = 1,
label = paste0(..count.., '개(', scales::percent(..prop..), ')')
),
stat= "count", vjust = -0.5) +
scale_y_continuous(labels = scales::percent) +
labs(y = '백분률')
데이터 막대 정렬
앞서 본 막대 그래프들은 모두 막대가 그 값에 관계없이 가나다 순으로 정렬되어 있다. 막대 그래프는 데이터간의 비교를 위해 많이 사용되는데 이런 정렬은 데이터간 비교에 다소 무리가 따른다. 예를 들어 세번째로 데이터가 많은 항목을 찾아라라고 한다면 사용자가 스스로 세 번째 데이터를 찾아야한다. 따라서 데이터 값의 순서로 막대를 정렬하면 더 비교가 편하게 될 것이다.
다만 이렇게 막대를 정렬해야하는 경우는 연속형 변수의 히스토그램은 사용할 수 없다. 연속형 변수에 대한 히스토그램은 막대의 구간이 순차적으로 정해지기 때문에 정렬이 큰 의미가 없기 때문이다.
이산형 히스토그램에 사용한 세가지 방법 모두 forcats::fct_infreq()
를 사용하면 정렬이 가능하다. forcats::fct_infreq()
은 매개변수로 전달하는 벡터를 팩터로 변환하고 그 빈도에 따라 레벨의 순서(order)를 설정해주는 함수이다.
## ..count..를 사용하는 방법
df_취업률_2000 |>
ggplot() +
geom_bar(aes(x = forcats::fct_infreq(대계열), y = ..count../sum(..count..))) +
geom_text(aes(x = forcats::fct_infreq(대계열), y = ..count../sum(..count..), group = 1,
label = paste0(..count.., '개(', scales::percent(..prop.., accuracy = 0.1), ')')
),
stat = 'count', vjust = -0.5
) +
scale_y_continuous(labels = scales::percent) +
labs(x = '대계열', y = '백분률')
## after_stat()을 사용한 방법
df_취업률_2000 |>
ggplot(aes(x = forcats::fct_infreq(대계열), y = after_stat(count/sum(count)))) +
geom_bar() +
geom_text(aes(label = paste0(after_stat(count), '개(', scales::percent(after_stat(count/sum(count))), ')')
),
stat= "count", vjust = -0.5) +
scale_y_continuous(labels = scales::percent) +
labs(x = '대계열', y = '백분률')
## ..prop..을 사용한 방법
df_취업률_2000 |>
ggplot() +
geom_bar(aes(x = forcats::fct_infreq(대계열), y = ..prop.., group = 1)) +
geom_text(aes(x = forcats::fct_infreq(대계열), y = ..prop.., group = 1,
label = paste0(..count.., '개(', scales::percent(..prop..), ')')
),
stat= "count", vjust = -0.5) +
scale_y_continuous(labels = scales::percent) +
labs(x = '대계열', y = '백분률')
위와 같이 특수한 함수를 사용하는 경우는 다소 어려운 방법임에 틀림없다. 일반적인 사용자라면 dplyr
를 사용하여 빈도와 비율을 구하도록 전처리하고 이 결과로 시각화하는 방법을 선호할 것이다. 어쩌면 이 방법이 더 효율적일수도 있을 것이다.
먼저 데이터 전처리를 해야하는데 group_by()
를 사용하여 변량별로 그룹화하고 이 그룹별로 사례수와 비율을 구하는 열을 추가해준다. 여기서 summarise()
와 mutate()
를 따로 사용하였는데 그 이유는 이전 포스트(https://2stndard.tistory.com/56)를 참조하라.
df_취업률_2000 |>
group_by(대계열) |>
summarise(n = n()) |>
mutate(rate = n/sum(n))
## # A tibble: 7 x 3
## 대계열 n rate
## <chr> <int> <dbl>
## 1 공학계열 536 0.268
## 2 교육계열 105 0.0525
## 3 사회계열 405 0.202
## 4 예체능계열 321 0.160
## 5 의약계열 87 0.0435
## 6 인문계열 217 0.108
## 7 자연계열 329 0.164
그리고 정렬을 위해서는 앞서 사용한 forcats::fct_infreq(대계열)
을 사용할 수도 있지만 reorder()
를 사용하였다. 하나 주의해야하는 것이 geom_bar()
의 stat
을 앞서 사용했던 ‘count’를 사용하지 않고 ’identity’를 사용했다는 것이다. 앞서 사용했던 방법들은 geom_bar()
에서 사례수를 카운트하는 통계처리가 필요하기 때문에 stat
을 ’count’ 로 설정했지만 미리 전처리되어 추가적인 통계처리가 필요하지 않고 수치 자체를 사용하기 때문에 그 수치를 통계변환하지 않고 자체로 사용하는 의미인 ’identity’를 설정하였다.
df_취업률_2000 |>
group_by(대계열) |>
summarise(n = n()) |>
mutate(rate = n/sum(n)) |>
ggplot() +
geom_bar(aes(x = reorder(대계열, n, desc), y = rate), stat = 'identity') +
geom_text(aes(x = reorder(대계열, n, desc), y = rate, label = paste0(n, '개(', scales::percent(rate), ')')), vjust = -0.5) +
scale_y_continuous(labels = scales::percent) +
labs(x = '대계열', y = '백분률')
'ggplot2' 카테고리의 다른 글
ggplot2 축 눈금 간격과 눈금 레벨 설정 in R (0) | 2022.05.05 |
---|---|
ggplot 이어 붙이기와 영국 이코노미스트지 스타일의 시각화 - 전문대학의 위기 (9) | 2022.05.02 |
비율(백분률)로 표현하는 히스토그램 in R (0) | 2022.04.22 |
geom_histogram의 bins와 binwidth (0) | 2022.04.21 |
벤다이어그램 in R (6) | 2022.02.19 |
댓글