R-Blogger블로그·해설한국어2025-11-22
ggplot2 Geoms 직접 작성하기 입문
ggplot2 확장 기능 만들기: 기초부터 실전까지 소개 ggplot2를 사용하면 geom_line()과 geom_point()를 이용해 차트를 만들게 되지만, ggridges의 geom_density_ridges()나 ggsignif의 geom_signif()처럼 더 폭넓은 ggplot2 생태계를 탐험할 수도 있습니다. 하지만 이런 확장 기능은 어떻게 만들어졌을까요? 저자가 새로운 geom을 만들 때 어떤 과정을 거쳤을지 궁금한 적이 있으셨나요? 원하는 플롯이 없을 때 직접 만들어 보는 방법을 알아보겠습니다. 저는 Posit(이전 RStudio)에서 일하면서 Gina Reynolds를 만나 Flipbookr에 대한 블로그 포스트를 작성했습니다. 이후 우리는 ggextenders 확장 클럽을 통해 연락을 이어가며, 매 몇 달마다 온라인 세미나를 열어 ggplot2 확장 기능에 관해 발표를 듣습니다. 이 과정에서 저는 ggstats와 같은 멋진 패키지를 배우게 되었고, 여러분도 언제든지 참여해 보실 수 있습니다. 저는 스스로 “ggextender”는 아니었으나, Gina가 진행한 Easy geom 레시피를 통해 확장 기능 만들기가 무섭지 않다는 것을 깨달았습니다. 이제 함께 geom_***() 를 만드는 과정을 따라 해 보겠습니다. Easy geom 레시피 따라하기 단계 0: 기본 ggplot2로 시작하기 확장 기능 아키텍처에 들어가기 전에 먼저 해야 할 일을 명확히 합니다. tidyverse와 palmerpenguins 패키지를 로드하고, bill_length_mm( x 변수)와 bill_depth_mm( y 변수)의 중앙값을 계산합니다. 이후 base ggplot2를 사용해 중앙값 포인트를 그립니다. library(tidyverse) library(palmerpenguins) penguins_medians <- penguins %>% summarize( bill_length_mm_median = median(bill_length_mm, na.rm = TRUE), bill_depth_mm_median = median(bill_depth_mm, na.rm = TRUE) ) penguins %>% ggplot() + aes(x = bill_depth_mm, y = bill_length_mm) + geom_point() + geom_point( data = penguins_medians, aes(x = bill_depth_mm_median, y = bill_length_mm_median), size = 8, color = "red" ) + labs(title = "Created with base ggplot2") 단계 1: compute 정의 및 테스트 입력 데이터를 내부에서 변환하는 compute 함수를 정의합니다. 아래 예시는 x와 y의 중앙값을 계산합니다. # Define compute. compute_group_medians <- function(data, ...) { summarize( x = median(x, na.rm = TRUE), y = median(y, na.rm = TRUE) ) } # Test compute. penguins %>% select(x = bill_depth_mm, y = bill_length_mm) %>% compute_group_medians() 결과는 1 × 2 tibble 으로 x=17.3, y=44.4가 반환됩니다. 단계 2: 새로운 Stat 정의 및 테스트 ggplot2::ggproto() 함수를 사용해 내부에서 계산을 수행하는 Stat 객체를 만듭니다. 대부분 boilerplate 코드이므로 직접 작성할 필요는 없습니다. 아래 예시는 StatMedians 객체를 정의한 뒤, geom_point에 stat=StatMedians로 적용해 테스트합니다. # StatMedians 정의 (boilerplate 예시) StatMedians <- ggplot2::ggproto( "StatMedians", ggplot2::Stat, required_aes = c("x", "y"), compute_group = compute_group_medians ) ggplot() + aes(x = bill_depth_mm, y = bill_length_mm) + geom_point() + geom_point(stat = StatMedians, size = 7) + labs(title = "Testing StatMedians") 단계 3: 사용자용 함수 정의 및 테스트 사용자가 호출할 수 있는 geom_medians() 함수와 stat_medians() 함수를 정의합니다. Stat 객체와 geom 객체는 이름이 다릅니다; Stat은 내부 계산 로직을 담당하고, geom은 레이어를 그립니다. # 사용자용 함수 예시 stat_medians <- function(mapping = NULL, data = NULL, ..., geom = "point") { layer( stat = StatMedians, data = data, mapping = mapping, geom = geom, position = "identity", show.legend = FALSE, inherit.aes = TRUE, ... ) } geom_medians <- function(mapping = NULL, data = NULL, ..., stat = stat_medians, geom = "point") { layer( stat = stat, data = data, mapping = mapping, geom = geom, position = "identity", show.legend = FALSE, inherit.aes = TRUE, ... ) } ggplot() + aes(x = bill_depth_mm, y = bill_length_mm) + geom_point() + geom_medians(size = 8) + labs(title = "Testing geom_medians()") 이제 geom_medians()와 stat_medians()를 사용해 원하는 플롯을 만들 수 있습니다. 마치며 Easy geom 레시피를 따라 하면 ggplot2 확장 기능을 만들 때 필요한 세 단계와 boilerplate 코드를 빠르게 이해할 수 있습니다. 만약 geom_means() 같은 새로운 geom을 만들고 싶다면 Easy geom recipes에서 대화형 튜토리얼을 진행해 보세요. 리소스 ggplot2 extenders club 웹사이트 이전 강연 보기 Everyday ggplot2 extension ggplot2 extension cookbook Easy geom recipes 감사 인사 Andrew Bray, James Goldie, QMD Lab의 Closeread, 그리고 Gina에게 특별히 감사드립니다. Gina는 ggplot2 extenders club을 조직하고 이 포스트를 리뷰해 주셨습니다.
원문 URL
전체 글은 원문 페이지에서 이어서 읽을 수 있습니다.
- 작성자
- R-Blogger
- 출처
- R-Blogger
- 플랫폼
- R-Blogger
- 분류
- 블로그·해설
- 언어
- 한국어
- 발행일
- 2025-11-22