[R] 결측치(Missing Values) 다루기

데이터를 다루다 보면 종종 빈칸으로 남은 값, 즉 결측치(Missing Values)를 만나게 된다. 예를 들어 설문 응답자가 키를 작성하지 않았거나 센서가 값을 기록하지 못했거나 수집 시스템의 오류로 누락된 값이 있을 수 있다.

결측치는 단순히 비어 있는 값처럼 보이지만, 적절히 처리하지 않으면 통계 분석과 모델링에 심각한 왜곡을 일으킬 수 있다. 따라서 분석을 시작하기 전에는 반드시 결측치를 탐색하고 처리해야 한다. R에서 결측치를 식별하고 처리하는 다양한 방법을 소개한다.

결측치란 무엇인가?

R에서 결측치는 NA (Not Available)로 표현된다. 빈 문자열(“”)이나 숫자 0과는 다르며, NA는 “값이 존재하지 않음”을 의미하는 특수한 상태이다. 예를 들어 다음과 같은 데이터프레임이 있다고 하자.

data <- tibble(
  name = c("Alice", "Bob", "Charlie", "David"),
  score = c(90, NA, 85, NA)
)
R

score 열에는 Bob과 David의 점수가 누락되어 있으며, NA로 표시된다.

결측치 탐색하기

1. 변수 전체에 결측치가 있는지 확인

# 열별 결측치 개수 확인
colSums(is.na(data))
R

2. 행 전체에서 결측치 확인

# 행별 결측치 개수
rowSums(is.na(data))
R

3. 특정 열만 확인하고 싶을 때

# score 열의 결측치 개수
sum(is.na(data$score))
R

4. 결측치가 포함된 행 추출

# score가 NA인 행
data %>% filter(is.na(score))
R

결측치 처리 방법

결측치를 무작정 삭제하거나 평균으로 대체하는 것은 항상 좋은 전략은 아니다. 데이터의 성격에 따라 적절한 처리 방식을 선택해야 한다. 아래는 대표적인 네 가지 처리 방법이다.

1. 결측치 제거

# 결측치가 있는 행 모두 제거
data_clean <- na.omit(data)
R

또는 특정 열만 기준으로 제거하고 싶다면

# score가 NA인 행만 제거
data_clean <- data %>% filter(!is.na(score))
R

2. 특정 값으로 대체 (예: 평균, 0, 기타)

# 평균 점수로 대체
mean_score <- mean(data$score, na.rm = TRUE)

data_filled <- data %>%
  mutate(score = if_else(is.na(score), mean_score, score))
R

3. 전후 값으로 채우기 (시계열 데이터 등)

# tidyr 패키지 사용
install.packages("tidyr")
library(tidyr)

data_filled <- data %>%
  fill(score, .direction = "down")  # 이전 값으로 채우기
R

4. 분석에서 제외 (계산할 때만 결측값 무시)

# 평균 계산 시 NA 제외
mean(data$score, na.rm = TRUE)
R

이 방법은 결측치를 유지하되 계산 시에만 무시한다. 통계 요약(mean, sd, sum)에서 자주 사용된다.

예제: starwars 데이터셋에서 결측치 처리

dplyr 패키지의 starwars 데이터에는 실제로 여러 열에 결측치가 포함되어 있다. 예를 들어 height, mass, birth_year 등에 NA가 포함되어 있다.

library(dplyr)

# 열별 결측치 개수
starwars %>%
  summarise(across(everything(), ~sum(is.na(.))))
R

1. height와 mass가 모두 존재하는 행만 필터링

starwars_clean <- starwars %>%
  filter(!is.na(height), !is.na(mass))
R

2. birth_year가 NA인 경우 “Unknown”으로 대체

starwars %>%
  mutate(birth_year = if_else(is.na(birth_year), -1, birth_year)) %>%
  select(name, birth_year)
R

요약 정리

함수/기능설명
is.na( )결측치 여부 확인
na.omit( )결측치가 포함된 행 제거
mutate(… = if_else(is.na(…), 대체값, …))결측치 대체
fill( )앞/뒤 값으로 결측치 보간(tidyr 사용)
na.rm = TRUE요약 통계 시 NA 제거 옵션

마무리하며

결측치는 대부분의 데이터셋에 존재하며, 이를 제대로 탐색하고 적절하게 처리하는 것이 분석의 시작이다. R에서는 다양한 함수와 패키지를 통해 결측치를 탐색하고 처리할 수 있으며, is.na( ), na.omit( ), mutate( ), fill( ) 등이 자주 사용된다.

실제 분석에서는 결측치가 왜 발생했는지 원인을 고려하고, 변수의 의미와 분석 목적에 따라 처리 방법을 선택하는 것이 중요하다.

1. 0과 NA는 다르다

0은 실제 값이며, NA는 존재하지 않는 값을 의미한다.

2. 빈 문자열(” “)과 NA도 다르다

문자형 데이터에서 빈 문자열은 ” “이고, 결측치는 NA_character_이다.

3. 계산 시 반드시 na.rm = TRUE 지정

NA가 포함된 벡터에서 평균, 합계 등을 구하려면 항상 na.rm = TRUE를 추가해야 한다.

4. 일괄 대체는 신중하게

평균이나 중앙값으로 일괄 대체할 경우 데이터 분포를 왜곡할 수 있다.

scroll to the top of the site