Post

R을 통한 시각화와 탐색적 데이터 분석(EDA)

R을 통한 시각화와 탐색적 데이터 분석(EDA)

시각화는 데이터 패턴을 직관적으로 이해하는 핵심 도구입니다. 오늘은 R의 ggplot2의 레이어 구조를 이용하여 복잡한 데이터를 시각화를 통해 체계적으로 구성해보도록 하겠습니다.


➤ 시각화의 목적

  1. 비교(Comparison)
  2. 구성(Composition)
  3. 분포(Distribution)
  4. 관계(Relationship)

➤ ggplot2의 구성 요소

함수설명
qplot()기하학적 객체와 미적 요소 매핑으로 스케일링
ggplot()미적 요소 매핑에 레이어 관련 함수 추가하여 플로팅, 미적 요소 재사용
ggsave()해상도 적용하여 다양한 형식의 이미지 파일 저장

ggplot2 핵심 구조

  1. Data
  2. Function
  3. Coordinates
  4. Mapping
  5. Geometries
  6. Scales
  7. Facets
  8. Themes

주요 시각화 도구

기본 차트 유형

  • 단변량 분석:
    • barplot, pie, stem
    • histogram, qqnorm
  • 다변량 분석:
    • plot, boxplot, pairs, curve

그래프 요소 추가 함수

  • title, lines, points, abline, text, segments, polygon
  • legend (범례), axis, box

ggplot2 작동 원리

  • 데이터: data.frame 형식 사용 (범주형 데이터 요약 가능)
  • 좌표계 종류:
    • 직교 좌표계 (Cartesian)
    • 극좌표계 (Polar)
    • 원통형 좌표계
    • 구형 좌표계
  • Geoms: 기하학적 객체 (예: points, lines, polygons)
  • Aesthetics(미적 요소):
    • 위치(position), 크기(size), 색상(color), 모양(shape), 투명도(alpha), 채움(fill)
  • 통계적 변환(Stats):
    • counts, means, median, 회귀선(regression lines) 등 집계 함수 적용
  • Facets: 화면 분할을 통한 다중 차트 생성
  • Themes: 그래프 스타일 커스터마이징

예제

# 기본 데이터 로드 data(cars) plot(cars$speed, type="l", main="속도 변화", xlab="측정 순서", ylab="속도") plot(cars, type="b", pch=22, cex=1.5, col="red")

다중 플롯 레이아웃

# 화면 분할 예제 opar <- par(mfrow=c(1,2)) hist(cars$speed, main="속도 분포") boxplot(cars$dist, main="제동거리 분포") par(opar)

ggplot2를 이용한 고급 시각화

기본 레이어 구조

library(ggplot2) ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point(aes(color=factor(cyl)), size=3) + labs(title="차량 중량 대비 연비", x="중량(톤)", y="연비(mpg)")

다중 차원 시각화

# 페이셋을 이용한 그룹별 시각화 ggplot(mpg, aes(displ, hwy)) + geom_point() + facet_wrap(~class, ncol=4) + geom_smooth(method="lm", se=FALSE)

지도 시각화

library(maps) asia <- map_data("world", region=c("South Korea", "Japan")) ggplot(asia, aes(long, lat, group=group, fill=region)) + geom_polygon(colour="black") + scale_fill_brewer(palette="Set3")

데이터 전처리

결측치 처리

# 결측치 확인 및 처리 sum(is.na(weatherAUS_d)) weather_clean <- na.omit(weatherAUS_d)

이상치 처리

# 박스플롯을 이용한 이상치 탐지 numeric_columns <- sapply(weatherAUS_d, is.numeric) re <- boxplot(numeric_columns) re # 이상치 확인 for (col_name in names(weatherAUS_d)[numeric_columns]) { outliers <- boxplot.stats(weatherAUS_d[[col_name]])$out weatherAUS_d[[col_name]][weatherAUS_d[[col_name]] %in% outliers] <- NA } weatherAUS_d<-na.omit(weatherAUS_d) re # 이상치 잘 제거 되었는지 확인

문자열 처리

정규표현식 활용

# 주 이름에서 'k'가 포함된 주 찾기 states <- rownames(USArrests) grep("k", states, value=TRUE, ignore.case=TRUE) # 문자열 패턴 대체 gsub("\\d", "_", "Secret Code: 007")

stringr 패키지 활용

library(stringr) str_c("Data", "Science", sep=" ") # 문자열 결합 str_detect(c("apple", "banana"), "a") # 패턴 검출

샘플링과 예측 모델링

데이터 분할

# 70-30 샘플링 set.seed(100) train_idx <- sample(1:nrow(weatherAUS_d), 0.7*nrow(weatherAUS_d)) train_data <- weatherAUS_d[train_idx,] test_data <- weatherAUS_d[-train_idx,]

시각화를 통한 인사이트 발굴

# 습도와 강수 관계 시각화 ggplot(train_data, aes(Humidity3pm, Temp3pm)) + geom_point(aes(color=RainTomorrow), alpha=0.6) + labs(title="오후 3시 기상 조건과 강수 예측", x="습도(%)", y="온도(℃)")

고급 시각화 테크닉

다중 그래프 배열

library(gridExtra) g1 <- ggplot(mtcars, aes(factor(cyl))) + geom_bar() g2 <- ggplot(mtcars, aes(wt, mpg)) + geom_point() grid.arrange(g1, g2, ncol=2)

밀도

library(ggplot2) library(gridExtra) g1=ggplot(mtcars, aes(x=qsec)) + geom_density(fill="slateblue") # 밀도 # theme : 그래프의 모양과 스타일을 커스터마이징, legend.position : 범례의 위치 g2=ggplot(mtcars, aes(x=drat, y=qsec, colour = cyl)) + geom_point(size=5) + theme(legend.position = "none") g3=ggplot(mtcars, aes(x=factor(cyl), y=qsec, fill = cyl)) + geom_boxplot() + theme(legend.position = "none") g4=ggplot(mtcars, aes(x=factor(cyl), fill = factor(cyl))) + geom_bar() grid.arrange(g1,g2,g3,g4, ncol=2,nrow=2) # 2열 2행 grid.arrange(g2, arrangeGrob(g3,g4,ncol=2),nrow=2) # g3,g4열로 2개, 2행 grid.arrange(g1,g2,g3, nrow=3) grid.arrange(g2, arrangeGrob(g3,g4,ncol=2),nrow=1)

수학 표현식 사용

# 그리스 문자 포함 축 레이블 ggplot(data.frame(x=1:10), aes(x)) + stat_function(fun=dnorm) + labs(x=expression(mu + sigma), y=expression(frac(1, sqrt(2*pi*sigma^2))))

선형회귀

# formula (종속변수 ~ 독립변수와의 관계) (m<-lm(dist ~ speed, data=cars)) (m<-lm(dist ~ speed, cars)) plot(cars) # 산점도 abline(m) # 보조 시각화 함수(선 추가, 회귀선(선형회귀)) (p<-predict(m, interval="confidence")) # predict : 예측 / 주로 선형 회귀 모델, 로지스틱 회귀 모델, 의사결정 트리 등 다양한 모델에서 활용 head(p) # lwr:하한값, upr:상한값 : fit +- 1.96 * 표준오차(표준변차/sqrt(n)) x<-c(cars$speed, tail(cars$speed, 1), rev(cars$speed), cars$speed[1]) # rev: reverse(역순으로) y<-c(p[, "lwr"], tail(p[, "upr"],1), rev(p[, "upr"]), p[, "lwr"][1]) # x,y 값으로 box 그리는 과정 polygon(x,y,col=rgb(.7,.7,.7,.5)) # (x축 : speed 값, y축 : 상하한값), rgb : (r,g,b, 투명도) (1,1,1 => 흰색 / 0,0,0 => 검정)

비선형회귀

opar <- par(mfrow=c(1,1)) plot(cars) lines(lowess(cars)) # lowess : 비선형회귀

이렇듯 2차원에서 여러 특징을 나타내는 법에 대해 간단히 알아보았습니니다. 이번 포스팅과 저번 포스팅에 배운 것을 이용하면 큰 데이터에서 적절하게 데이터를 샘플링하여 각 요소별로 결과에 어떤 영향을 주는지 분석해 볼 수 있을 것입니니다. 날씨 데이터에서 오후3시 날씨와 습도가 다음날 비가 오는데 영향을 주는지 ggplot2로 한번 나타내 보세요요. 이때, geom_density를 이용하면 그 영향을 보기 더 편할 것입니다.

This post is licensed under CC BY 4.0 by the author.