광고 회사에서 캠페인 결과 데이터를 보며 가장 빠지기 쉬운 함정은 '평균의 함정'이 아닐까..? 평균만 보고 '음 이 광고는 잘됐군. 음 이 광고는 안됐군.' 하는 것 말이다.
물론.. 평균값을 보는게 잘못됐다는 게 절대 아닙니다. 평균값'만' 보는 것을 이야기 하는 것이지요. 이런 점에서 저는 boxplot이 참 좋습니다. boxplot은 양적 데이터로부터 얻어낸 다섯 가지 요약 수치를 모두 동등하게, 빠르게, 한눈에 보여주거든요.
해서, 이 블로그의 첫 글의 주제를 "R로 boxplot 그리는 법"으로 잡아 보았습니다. boxplot이 무엇인지와 ggplot2 패키지를 통해 R로 표현하는 방법을 알아봅시다.🤩
기술통계학에서 상자그림 혹은 상자수염그림 이라고 부르는 이 그래프는 자료로부터 얻어낸 여러가지 요약수치들를 한 눈에 표현합니다. 상자수염그림은 상자 양옆에 기다란 줄이 나있는 형태여서 붙여진 이름이라 하네요.
🍎bloxplot 지표
1) 최솟값 (minumum)
2) 최댓값 (Maximum)
3) 중앙값 (Median)
4) 1사분범위 (1Q, 즉 하위 25% 지점)
5) 3사분범위 (3Q, 즉 상위 25% 지점)
6) IQR (inter-quartile range) :
IQR은 1Q~3Q 구간인데요, 최솟값과 최댓값 범위는 데이터의 추세와는 맞지 않게 갑자기 크거나 작거나 하는 이상치에 영향을 많이 받습니다. 해서 이상치에 영향을 받지 않는 IQR을 살펴보는 것이 꼭 필요하겠지요.
7) 이상치 (Outlier) :
1Q, 3Q, IQR을 통해 상위 이상치(= Q1 - 1.5 * IQR)와 하위 이상치(= Q3 - 1.5 * IQR)를 알 수 있습니다. 이상치가 있다면 데이터에 오류가 있는건 아닌지 확인을 해야합니다. 데이터의 이상치가 진짜라면 왜 발생된 것인지 파악해야 합니다.
그렇다면 R로 boxplot을 어떻게 그릴까요? R에서 기본으로 제공하는 bloxplot함수와 ggplot2를 통해 그리는 방법이 있습니다. 저는 ggplot2로 그려 보았습니다. 활용한 데이터는 ggplot2에 내장되어 있는 diamonds입니다.
(참고) diamonds 데이터?
그래프를 잘 표현해주는 ggplot2에 내장되어 있는 예제 데이터로,
약 5만개 다이아몬드에 대한 cut, clarity, color, length 등의
변수가 있습니다.
y값만 설정한 boxplot입니다.
library(tidyverse) # ggplot2는 tidyverse를 불러오면 함께 불러와집니다.
diamonds %>%
ggplot2::ggplot(mapping = aes(y = price)) + # Y를 price 변수로 지정
ggplot2::geom_boxplot() # price 변수를 기준으로 boxplot 생성
이번엔 price 수치의 하나의 boxplot으로 보는 것이 아니라, cut(다이아 몬드의 대칭, 비례 및 광택 수준) 그룹별로 비교해볼 거에요.
library(RColorBrewer) # RColorBrewer 불러오기
RColorBrewer::display.brewer.all() #팔레트 확인
myPal <- RColorBrewer::brewer.pal(n = 5, name = "Pastel2") # 위 팔레트 중 마음에 드는 것을 골라 myPal에 저장!
diamonds %>%
ggplot2::ggplot(mapping = aes(y = price, x = cut, group = cut)) + # cut을 기준으로 그루핑
ggplot2::geom_boxplot(fill = myPal, colour = "snow4", alpha = 0.5, outlier.color = "red", outlier.size = 0.3) + # 앞서 저장한 myPal로 boxplot 색 채우기. 그 외 아웃라인과 이상치 색상도 지정
ggplot2::theme_classic() + # 그래프 테마 지정
ggplot2::theme(axis.title.x = element_text(size = 10, face = "italic", color = "gray", angle = 0, vjust = 0.5),
axis.title.y = element_text(size = 10, face = "bold.italic", color = "gray", angle = 0, vjust = 0.5)) + # X축과 Y축의 서식 스타일 지정
ggplot2::scale_y_continuous(labels = scales::comma) # Y 값의 천단위에 콤마 표시
diamonds %>%
ggplot2::ggplot(mapping = aes(y = price, x = cut, group = cut)) +
ggplot2::geom_boxplot(fill = myPal, colour = "snow4", alpha = 0.5, outlier.shape = NA) + # 이상치 제거
ggplot2::theme_classic() +
ggplot2::theme(axis.title.x = element_text(size = 10, face = "italic", color = "gray", angle = 0, vjust = 0.5),
axis.title.y = element_text(size = 10, face = "bold.italic", color = "gray", angle = 0, vjust = 0.5)) +
ggplot2::scale_y_continuous(labels = scales::comma)
diamonds %>%
ggplot2::ggplot(mapping = aes(y = price, x = cut, group = cut)) +
ggplot2::geom_boxplot(fill = myPal, colour = "snow4", alpha = 0.5, outlier.shape = NA) + # 이상치 제거
ggplot2::theme_classic() +
ggplot2::theme(axis.title.x = element_text(size = 10, face = "italic", color = "gray", angle = 0, vjust = 0.5),
axis.title.y = element_text(size = 10, face = "bold.italic", color = "gray", angle = 0, vjust = 0.5)) +
ggplot2::scale_y_continuous(labels = scales::comma) +
ggplot2::coord_flip() # X, Y 위치 전치
diamonds %>%
ggplot2::ggplot(mapping = aes(y = price, group = cut)) +
ggplot2::geom_boxplot(fill = myPal, colour = "snow4", alpha = 0.5, outlier.shape = NA) +
ggplot2::theme_classic() +
ggplot2::theme(axis.title.x = element_text(size = 10, face = "italic", color = "gray", angle = 0, vjust = 0.5),
axis.title.y = element_text(size = 10, face = "bold.italic", color = "gray", angle = 0, vjust = 0.5)) +
ggplot2::scale_y_continuous(labels = scales::comma) +
ggplot2::coord_flip() +
ggplot2::facet_wrap(~cut) # cut 기준 권역 분리 설정
아래와 같이 사용자 함수로 ggplot2의 그래프 서식을 저장하면 여러 버전의 그래프 생성 시에 코드를 모두 작성하지 않고 빠르게 만들 수 있습니다.
myPlotTheme <- function(x){
x +
ggplot2::theme_classic() +
ggplot2::geom_boxplot(fill = myPal, colour = "snow4", alpha = 0.5, outlier.shape = NA) +
ggplot2::theme(axis.title.x = element_text(size = 10, face = "italic", color = "gray", angle = 0, vjust = 0.5),
axis.title.y = element_text(size = 10, face = "bold.italic", color = "gray", angle = 0, vjust = 0.5)) +
ggplot2::scale_y_continuous(labels = scales::comma)
}
이렇게 boxplot을 통해 한 눈에 데이터의 요약수치를 본 뒤에는 이 대표값들이 뜻한 바가 무엇인지 해석해보면 좋을 것 같습니다. 또 어디에 숨어져있을 지 모를 인사이트를 찾기위해 또 다른 방법으로 시각화를 해보아도 좋구요 😇
R 입문자, 완전 초보자 이지만.. 앞으로 R 시각화 방법을 계속 써볼 생각이에요. 오늘의 포스팅은 이만 마치겠습니다. 감사합니다 ❕