데이터를 다루다 보면 종종 빈칸으로 남은 값, 즉 결측치(Missing Values)를 만나게 된다. 예를 들어 설문 응답자가 키를 작성하지 않았거나 센서가 값을 기록하지 못했거나 수집 시스템의 오류로 누락된 값이 있을 수 있다.
결측치는 단순히 비어 있는 값처럼 보이지만, 적절히 처리하지 않으면 통계 분석과 모델링에 심각한 왜곡을 일으킬 수 있다. 따라서 분석을 시작하기 전에는 반드시 결측치를 탐색하고 처리해야 한다. R에서 결측치를 식별하고 처리하는 다양한 방법을 소개한다.
결측치란 무엇인가?
R에서 결측치는 NA (Not Available)로 표현된다. 빈 문자열(“”)이나 숫자 0과는 다르며, NA는 “값이 존재하지 않음”을 의미하는 특수한 상태이다. 예를 들어 다음과 같은 데이터프레임이 있다고 하자.
data <- tibble(
name = c("Alice", "Bob", "Charlie", "David"),
score = c(90, NA, 85, NA)
)
Rscore 열에는 Bob과 David의 점수가 누락되어 있으며, NA로 표시된다.
결측치 탐색하기
1. 변수 전체에 결측치가 있는지 확인
# 열별 결측치 개수 확인
colSums(is.na(data))
R2. 행 전체에서 결측치 확인
# 행별 결측치 개수
rowSums(is.na(data))
R3. 특정 열만 확인하고 싶을 때
# score 열의 결측치 개수
sum(is.na(data$score))
R4. 결측치가 포함된 행 추출
# score가 NA인 행
data %>% filter(is.na(score))
R결측치 처리 방법
결측치를 무작정 삭제하거나 평균으로 대체하는 것은 항상 좋은 전략은 아니다. 데이터의 성격에 따라 적절한 처리 방식을 선택해야 한다. 아래는 대표적인 네 가지 처리 방법이다.
1. 결측치 제거
# 결측치가 있는 행 모두 제거
data_clean <- na.omit(data)
R또는 특정 열만 기준으로 제거하고 싶다면
# score가 NA인 행만 제거
data_clean <- data %>% filter(!is.na(score))
R2. 특정 값으로 대체 (예: 평균, 0, 기타)
# 평균 점수로 대체
mean_score <- mean(data$score, na.rm = TRUE)
data_filled <- data %>%
mutate(score = if_else(is.na(score), mean_score, score))
R3. 전후 값으로 채우기 (시계열 데이터 등)
# tidyr 패키지 사용
install.packages("tidyr")
library(tidyr)
data_filled <- data %>%
fill(score, .direction = "down") # 이전 값으로 채우기
R4. 분석에서 제외 (계산할 때만 결측값 무시)
# 평균 계산 시 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(.))))
R1. height와 mass가 모두 존재하는 행만 필터링
starwars_clean <- starwars %>%
filter(!is.na(height), !is.na(mass))
R2. 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. 일괄 대체는 신중하게
평균이나 중앙값으로 일괄 대체할 경우 데이터 분포를 왜곡할 수 있다.