R tidyverse·ggplot2·caret로 구성하는 분석 파이프라인
tidyverse, ggplot2, caret를 연결해 R 데이터 전처리·시각화·모델링 파이프라인의 일관성과 재현성을 확보하는 방법
2026-08-14 · 최초 발행 2024-04-29
전처리부터 모델 평가까지 이어지는 R 분석 흐름
분석 과정이 전처리 스크립트, 탐색용 그래프, 모델 학습 코드로 분리되면 변경 사항을 추적하고 결과를 다시 만드는 일이 어려워진다. tidyverse의 dplyr·tidyr, ggplot2, caret를 함께 쓰면 데이터 변환부터 시각화, 분류·회귀 모델링까지 일관된 파이프라인으로 구성할 수 있다.
tidyverse는 데이터 가공·변환·입출력 프레임워크를 제공하는 R 패키지 모음이다. dplyr은 행과 열을 다루는 선언적 문법을 제공하고, tidyr은 넓은 형식과 긴 형식 사이의 변환, 결측 구조 정리에 쓰인다.
ggplot2는 Layered Grammar of Graphics에 기반한 선언적 시각화 시스템이다. 데이터, 미학 매핑, 기하 객체, 통계 변환, 좌표, 테마를 레이어로 조합한다.
caret은 전처리, 교차검증, 하이퍼파라미터 탐색, 성능 지표 관리를 포함해 200+ 모델의 학습·튜닝·검증을 통일된 인터페이스로 지원하는 래퍼 프레임워크다.
변환 규칙과 데이터 구조를 먼저 맞춘다
dplyr에서는 select, filter, summarise, join을 중심으로 변환을 선언적으로 연결할 수 있다. 처리 의도가 코드에 드러나므로 가독성과 테스트 용이성을 높이는 데 유리하다.
tidyr의 pivot_longer, pivot_wider, separate, unite는 분석에 맞는 데이터 구조를 만드는 데 사용한다. 결측값 처리와 스키마 정합성을 함께 관리할 수 있다.
그래프를 진단과 설명의 공통 산출물로 쓴다
ggplot2는 데이터·aes·geom·stat·facet·theme를 계층적으로 구성한다. 탐색적 분석에서 만든 그래프를 설명형 시각화로 발전시키기 쉽고, 스케일·좌표·주석 레이어를 더해 리포팅용 도식으로 확장할 수 있다. 같은 코드에서 같은 플롯을 생성하는 흐름도 유지할 수 있다.
caret으로 학습과 비교 기준을 통일한다
caret의 train() 중심 API는 모델 정의, resampling(교차검증·부트스트랩), 튜닝 그리드 관리를 한 흐름에 둔다. preProcess를 통해 전처리 단계를 모델링 과정에 포함해 데이터 누수를 방지하는 구성을 만들 수 있다.
Accuracy, Kappa, RMSE, ROC 같은 성능 지표를 같은 기준으로 관리할 수 있어 모델 간 비교와 파이프라인 자동화에 적합하다.
입력에서 산출물까지 끊기지 않게 구성한다
입력, 전처리, EDA, 특성공학, 모델링, 평가, 출력의 흐름을 명확히 두면 스크립트와 프로젝트 구조를 통해 변경 영향을 줄일 수 있다. 시드를 고정하고 버전을 명시하며, 모형·메타데이터·그림 같은 결과 아티팩트를 저장하는 방식이 재현성 관리의 기반이 된다.
입력 단계에서는 CSV·DB 커넥터, 스키마 정의, 타입 캐스팅을 다룬다. 처리 단계에는 전처리 규칙, 시각화 점검, 교차검증·튜닝이 포함된다. 출력은 모델·지표·그림·로그로 구성하며, 실패 시 롤백·재시도 정책도 함께 둔다.
| 구성 | 성능 | 확장성 | 일관성 | 안정성 | 운영 편의 |
|---|---|---|---|---|---|
| dplyr/tidyr | 중~상: 메모리 내 벡터화 | 중: 메모리 기반, DB 백엔드로 확장 가능 | 상: 선언적 문법 | 상: 타입/스키마 명시 용이 | 상: 파이프라인 가독성 |
| ggplot2 | 중: 대용량 시 샘플링 권장 | 중: 정적 렌더링 중심 | 상: 문법 일관 | 상: 재현 가능한 플롯 | 상: 테마/스케일 재사용 |
| caret | 중: 래퍼 오버헤드 존재 | 중: 병렬 CV로 확장 | 상: 지표·튜닝 표준화 | 상: 재현성 관리 도구 | 중~상: 단일 API, 의존 패키지 관리 필요 |
대용량 데이터를 다룰 때는 data.table, Arrow, Spark 연계를 고려할 수 있다. 모델 최신화가 필요한 경우에는 tidymodels의 parsnip, workflows도 대안으로 검토한다.
분석 목적에 따라 이어지는 활용 흐름
제조 공정 불량률 예측에서는 설비 로깅 데이터와 로트 메타데이터를 입력으로 사용한다. dplyr 조인과 결측 대체 후 ggplot2로 공정능력을 진단하고, caret 회귀 모델에서 RMSE 최소화를 목표로 한다. 결과는 예측 불량률 대시보드와 경보 임계치로 연결된다.
이커머스 전환율 분석·예측에서는 세션 로그와 캠페인 태그를 다룬다. tidyr로 세션 이벤트를 피벗하고 ggplot2로 퍼널·히트맵을 만든 뒤, caret 분류에서 ROC AUC 최대화를 기준으로 삼는다. 캠페인 성과 리포트와 타깃팅 세그먼트가 산출물이다.
금융 신용 리스크 스코어링은 거래·신상·상환 이력을 입력으로 한다. 파생변수를 만들고 이분화 기준을 최적화한 다음 ggplot2로 KS·ROC를 진단하고, caret 교차검증·튜닝을 수행한다. 스코어 카드와 리스크 컷오프 정책으로 이어진다.
단일 스크립트로 실행하는 예시
전제조건: R ≥ 4.2, tidyverse ≥ 2.0, ggplot2 ≥ 3.5, caret ≥ 6.0-94, rpart ≥ 4.1-19
설치: install.packages(c("tidyverse","ggplot2","caret","rpart"))
# 1) 패키지 로드 및 시드
library(tidyverse)
library(ggplot2)
library(caret)
set.seed(2025)
# 2) 데이터 준비: mtcars 회귀 예시 (mpg 예측)
df <- mtcars %>%
rownames_to_column("model") %>%
as_tibble() %>%
mutate(
cyl = factor(cyl),
am = factor(am, labels = c("auto","manual"))
)
# 3) EDA: ggplot2 레이어드 그래픽
p <- ggplot(df, aes(wt, mpg, color = am)) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = TRUE) +
facet_wrap(~ cyl) +
labs(title = "MPG vs Weight by Transmission and Cylinders",
x = "Weight (1000 lbs)", y = "Miles per Gallon") +
theme_minimal()
print(p)
# 4) 학습/검증 분할
set.seed(2025)
idx <- createDataPartition(df$mpg, p = 0.8, list = FALSE)
train_df <- df[idx, ]
test_df <- df[-idx, ]
# 5) caret 학습 설정: 5-겹 CV, 전처리 포함
ctrl <- trainControl(method = "cv", number = 5)
# 간단·안정 의존성을 위해 rpart(회귀 트리) 사용
set.seed(2025)
model <- train(
mpg ~ wt + hp + cyl + am,
data = train_df,
method = "rpart",
trControl = ctrl,
preProcess = c("center","scale")
)
print(model)
# 6) 성능 평가
pred <- predict(model, newdata = test_df)
rmse <- RMSE(pred, test_df$mpg)
r2 <- R2(pred, test_df$mpg)
cat(sprintf("Test RMSE: %.3f, R2: %.3f\n", rmse, r2))
# 7) 잔차 진단 플롯
res_df <- tibble(obs = test_df$mpg, pred = pred, resid = obs - pred)
ggplot(res_df, aes(pred, resid)) +
geom_hline(yintercept = 0, color = "red") +
geom_point() +
labs(title = "Residuals vs Fitted", x = "Predicted MPG", y = "Residuals") +
theme_minimal()
스키마는 stopifnot(all(c("wt","hp","cyl","am","mpg") %in% names(df)))로 확인할 수 있다. 누락치는 tidyr::replace_na 또는 모델 입력 전 complete.cases 필터로 처리한다. 재현성을 위해 set.seed를 고정하고 sessionInfo()를 기록하며, 패키지 버전은 pyproject에 비유해 renv 사용을 권장한다.
ETL/EDA 시간은 3050% 단축되고 코드 라인 수는 2040% 감소할 수 있다. 교차검증·튜닝 자동화는 재학습 주기당 운영 인력 투입을 2535% 절감하며, 표준 지표 관리는 모델 성능 변동성을 1525% 낮춘다.
이 조합은 파이프라인의 일관성과 가독성을 높여 코드 리뷰와 온보딩 난이도를 낮춘다. 시각화 표준화는 의사결정 속도와 커뮤니케이션 비용에 영향을 주며, 재현 가능성과 감사 추적성은 거버넌스 준수를 수월하게 한다. 운영 단계에서는 대용량 처리용 외부 백엔드·병렬화, 버전 고정, 모니터링 체계를 함께 적용한다.