Categories: R

R에서 결측치(NA) 처리 방법 (is.na(), na.omit(), na.rm = TRUE)

데이터 분석하면서 늘 골치 아픈 존재, 바로 결측치(NA)죠? 마치 퍼즐 조각이 몇 개 빠진 것처럼 답답하고, 분석 결과를 엉망으로 만들기도 하잖아요. R을 이용해서 분석하는 분들이라면 누구나 한 번쯤은 이 결측치 때문에 밤잠 설친 경험 있으실 거예요. 그래서 오늘은 R에서 이 결측치(NA)를 다루는 꿀팁들을 알려드리려고 해요!

is.na() 함수처럼 결측치를 확인하는 기본적인 방법부터 na.omit(), na.rm = TRUE결측치를 제거하거나 계산에 포함하는 방법까지 차근차근 살펴볼 거예요. 다양한 결측치 처리 방법을 비교하며 상황에 맞는 최적의 방법을 찾는 것도 중요하답니다. 자, 이제 함께 결측치 정복 여정을 떠나볼까요?

 

 

결측치 확인하기

데이터 분석의 세계에 뛰어들다 보면, 마치 숨바꼭질처럼 자주 마주치는 녀석이 있죠? 바로 결측치(NA: Not Available)입니다! 마치 퍼즐 조각이 몇 개 빠진 것처럼, 완벽한 분석을 방해하는 골칫덩어리라고 할 수 있어요. 하지만 너무 걱정하지 마세요! R은 이런 결측치를 다루는 데 필요한 강력한 도구들을 제공하니까요. R과 함께라면 결측치? 문제없어요!

결측치 확인하기

가장 먼저 해야 할 일은 데이터 안에 결측치가 어디에, 얼마나 숨어 있는지 확인하는 거예요. 마치 탐정이 된 기분으로 꼼꼼하게 살펴보자고요! R에서는 is.na() 함수가 이 역할을 톡톡히 해냅니다. is.na() 함수는 결측치를 찾아내 “TRUE”라는 깃발을 꽂아주는 역할을 해요. 마치 보물찾기에서 보물을 찾으면 “찾았다!”라고 외치는 것과 같죠. 반대로 값이 있는 곳에는 “FALSE” 깃발을 꽂아줍니다.

예를 들어, my_data라는 데이터 프레임에 age, gender, income이라는 변수가 있다고 가정해 볼게요. is.na(my_data$age)를 실행하면, age 변수에 결측치가 있는 행에는 TRUE, 값이 있는 행에는 FALSE가 표시됩니다. 아주 간단하죠?

is.na() 함수는 단순히 결측치의 유무뿐 아니라, 그 개수까지 알려주는 똑똑한 기능도 갖고 있어요. sum(is.na(my_data$age))와 같이 sum() 함수와 함께 사용하면 age 변수에 존재하는 결측치의 총 개수를 짠! 하고 보여준답니다. 만약 결과가 0이라면? 축하드려요! 해당 변수에는 결측치가 하나도 없다는 뜻이에요! 하지만 0보다 큰 숫자가 나온다면? 결측치 처리를 위한 다음 단계로 넘어가야겠죠?

데이터 프레임에서 결측치 위치 및 개수 파악

자, 이제 전체 데이터 프레임에서 결측치의 위치와 개수를 파악하는 방법을 알아볼게요. is.na(my_data)를 실행하면 각 셀에 대해 TRUE/FALSE 값을 가진 행렬 형태의 결과를 얻을 수 있어요. 여기에 summary() 함수를 적용하면 각 변수별 결측치 개수를 한눈에 확인할 수 있답니다! 정말 편리하죠? colSums(is.na(my_data))를 사용하면 각 열(변수)별로 결측치의 합계를 계산할 수 있어요. 마치 엑셀에서 SUM 함수를 사용하는 것과 비슷하다고 생각하면 돼요.

결측치 처리 시작

이렇게 결측치의 위치와 개수를 파악했다면 이제 본격적인 결측치 처리를 시작할 수 있어요. 결측치를 제거할지, 다른 값으로 대체할지, 아니면 그대로 둘지… 다양한 방법들이 있으니 상황에 맞는 최적의 방법을 선택하는 것이 중요해요. 결측치 처리는 데이터 분석 결과에 큰 영향을 미칠 수 있기 때문에 신중하게 접근해야 한답니다!

결측치 패턴 파악

때로는 결측치가 특정 패턴을 가지고 나타나는 경우도 있어요. 예를 들어 특정 연령대나 성별에서 결측치가 많이 발생할 수 있죠. 이런 패턴을 파악하는 것도 매우 중요해요! table(my_data$gender, is.na(my_data$income))와 같이 table() 함수를 사용하면 성별에 따른 소득 변수의 결측치 발생 빈도를 교차표 형태로 확인할 수 있답니다. 만약 특정 그룹에서 결측치가 유독 많다면, 그 이유를 꼼꼼히 분석해봐야 해요. 숨겨진 데이터의 비밀을 풀어낼 수 있는 중요한 단서가 될 수도 있으니까요!

결측치를 확인하는 것은 마치 건물의 기초 공사와 같아요. 기초가 튼튼해야 멋진 건물을 지을 수 있듯이, 정확한 결측치 확인은 정확한 데이터 분석 결과를 위한 첫걸음이라고 할 수 있죠. R과 함께라면 결측치라는 험난한 산도 거뜬히 넘을 수 있을 거예요! 자, 이제 다음 단계로 넘어가 볼까요?

 

결측치 제거하기

휴~, 결측치 확인까지 잘 따라오셨나요? 이제 본격적으로 결측치를 제거하는 방법에 대해 알아볼게요! 결측치를 발견했다면 이제 어떻게 처리해야 할지 고민되시죠? 분석 목표나 데이터 특성에 따라 여러 가지 방법이 있지만, 가장 흔하게 쓰이는 방법 중 하나가 바로 결측치가 포함된 행이나 열 전체를 싹~ 없애버리는 거예요! 마치 퍼즐 조각에서 빈 부분을 도려내는 것과 비슷하다고 생각하면 돼요! ^^

R에서 결측치 제거

R에서는 na.omit() 함수와 complete.cases() 함수를 사용해서 결측치가 있는 행 전체를 제거할 수 있어요. 마치 정원에서 잡초를 뽑아내듯이 말이죠! 예를 들어, 100개의 관측치와 5개의 변수로 이루어진 데이터 프레임에서 3개의 관측치에 결측치가 있다면, na.omit() 함수를 적용하면 결측치가 있는 3개의 행이 제거되고 97개의 관측치만 남게 되는 거죠. 간단하죠?

# 예시 데이터 생성
df <- data.frame(
  A = c(1, 2, NA, 4, 5),
  B = c(NA, 7, 8, 9, 10),
  C = c(11, 12, 13, NA, 15)
)

# na.omit() 함수를 사용하여 결측치가 있는 행 제거
df_omit <- na.omit(df)
print(df_omit)

# complete.cases() 함수를 사용하여 결측치가 없는 행 추출
df_complete <- df[complete.cases(df), ]
print(df_complete)

complete.cases() 함수는 결측치가 없는 행에 대해 TRUE를, 결측치가 있는 행에 대해 FALSE를 반환해요. 이 결과를 이용해서 TRUE인 행만 추출하면 결측치가 없는 데이터만 남게 되는 거죠! 마치 체로 거르는 것과 비슷해요! na.omit() 함수와 결과는 동일하지만, 조금 다른 방식으로 작동한다는 점 기억해두세요~!

결측치 제거 시 주의사항

하지만, 결측치 제거는 데이터 손실로 이어질 수 있다는 점 꼭! 명심해야 해요! 특히 결측치가 많은 데이터셋에서는 중요한 정보를 잃어버릴 수도 있거든요. 예를 들어, 1000개의 관측치 중 500개의 관측치에 결측치가 있다면, na.omit() 함수를 사용하면 절반의 데이터가 사라지는 거예요. 으악! 상상만 해도 아찔하죠?! 그렇기 때문에 결측치 제거는 신중하게 결정해야 해요!

특정 변수 제거

만약 특정 변수에 결측치가 많아서 그 변수 자체를 제거하고 싶다면 어떻게 해야 할까요? R에서는 간단하게 해당 변수를 NULL로 설정하면 돼요. 예를 들어, ‘age’라는 변수를 제거하고 싶다면 df$age <- NULL 이라고 입력하면 끝! 참 쉽죠?

# 'age' 변수 제거
df$age <- NULL
print(df)

결측치 제거는 간단하지만, 데이터 분석 결과에 큰 영향을 미칠 수 있는 중요한 작업이에요. 마치 요리에서 재료 손질이 중요한 것처럼 말이죠! 데이터의 특성과 분석 목적을 잘 고려해서 신중하게 결측치를 제거해야 분석 결과의 신뢰성을 높일 수 있다는 점 잊지 마세요~! 😉 다음에는 결측치를 제거하는 대신 다른 값으로 대체하는 방법에 대해 알아볼 거예요. 기대해주세요! ✨

 

결측치 포함 계산하기

휴~, 결측치를 확인하고 제거하는 방법을 알아봤으니 이제 실전으로 넘어가 볼까요? 데이터 분석에서 결측치는 정말 골칫덩어리잖아요? ^^; 있으면 분석 결과를 왜곡시키기도 하고, 함수 실행을 막기도 하니까요! 그런데 무작정 결측치를 제거하는 게 항상 옳은 방법은 아니라는 거, 알고 계셨나요? 때로는 결측치를 포함한 상태로 계산해야 더 정확한 분석 결과를 얻을 수 있답니다. 자, 그럼 어떻게 하는지 같이 살펴볼까요~?

R의 결측치 포함 계산 기능

R은 결측치를 포함한 상태로 계산할 수 있는 다양한 기능을 제공해요. 대표적으로 na.rm = TRUE 인자를 사용하는 방법이 있죠. 이 인자는 함수에 따라 조금씩 다르게 작동하지만, 기본적으로 결측치를 제외하고 계산하도록 지시하는 역할을 해요. 마치 “결측치는 잠시 옆으로 빠져있어!~”라고 말하는 것 같죠? ^^

na.rm = TRUE 활용 예시

예를 들어, 평균값을 구하는 mean() 함수에 na.rm = TRUE 인자를 추가하면 결측치를 제외한 나머지 값들의 평균을 계산해 줘요. sum(), sd(), var() 등 다른 통계 함수에도 이 인자를 적용할 수 있답니다. 정말 편리하죠?!

# 벡터 생성 (결측치 포함)
my_vector <- c(1, 2, NA, 4, 5, NA, 7)

# 결측치 제외 평균 계산
mean(my_vector, na.rm = TRUE)  # 결과: 3.8

# 결측치 제외 합계 계산
sum(my_vector, na.rm = TRUE) # 결과: 19

# 결측치 제외 표준편차 계산
sd(my_vector, na.rm = TRUE) # 결과: 2.13809

# 결측치 제외 분산 계산
var(my_vector, na.rm = TRUE) # 결과: 4.571429

na.rm = TRUE 인자를 사용하지 않으면 어떻게 될까요? 결과는 NA가 나와버려요! 마치 R이 “결측치 때문에 계산을 못 하겠어요 ㅠㅠ”라고 말하는 것 같죠? 이럴 때 na.rm = TRUE가 구세주처럼 등장하는 거예요!

하지만 모든 함수가 na.rm = TRUE 인자를 지원하는 것은 아니라는 점! 꼭 기억해 두세요. 함수의 도움말을 확인하거나 구글링을 통해 해당 함수가 na.rm = TRUE를 지원하는지 확인하는 습관을 들이는 것이 좋답니다.

다른 결측치 처리 방법

na.rm = TRUE 외에도 결측치를 포함한 계산을 위한 다양한 방법들이 있어요. 예를 들어, 특정 값으로 대체하거나(imputation), 결측치가 있는 행이나 열 전체를 제거하지 않고 분석하는 방법 등이 있죠. 상황에 따라 적절한 방법을 선택하는 것이 중요해요. 마치 요리할 때 레시피에 따라 재료와 조리법을 선택하는 것과 같다고 할까요?

결측치를 포함한 계산은 데이터 분석에서 매우 중요한 부분이에요. na.rm = TRUE처럼 간단한 방법부터 복잡한 기법까지 다양한 방법을 익혀두면 데이터 분석 능력을 한 단계 업그레이드할 수 있을 거예요! 다음에는 더욱 흥미로운 주제로 찾아올게요! 기대해 주세요~ 😉

Imputation 기법

자, 이제 조금 더 깊이 들어가 볼까요? 결측치를 특정 값으로 대체하는 imputation 기법에 대해 좀 더 자세히 알아보도록 하죠. imputation은 결측치를 제거하지 않고, 특정 값으로 대체하여 데이터의 손실을 최소화하는 기법이에요. 평균값, 중앙값, 최빈값 등으로 대체하는 방법이 일반적으로 사용되죠. 어떤 값으로 대체할지는 데이터의 특성과 분석 목적에 따라 결정해야 한답니다. 마치 옷을 고를 때 TPO에 맞춰 선택하는 것처럼 말이죠!

# mice 패키지 설치 및 로드 (필요한 경우)
# install.packages("mice")
library(mice)

# 간단한 데이터 프레임 생성 (결측치 포함)
df <- data.frame(
  A = c(1, 2, NA, 4, 5),
  B = c(6, NA, 8, 9, 10)
)

# mice 함수를 사용하여 결측치 대체 (predictive mean matching 방법 사용)
imputed_df <- mice(df, m = 1, maxit = 5, method = "pmm", seed = 500)

# 대체된 데이터 프레임 확인
completed_df <- complete(imputed_df)
print(completed_df)

위의 예시 코드에서는 mice 패키지를 사용하여 결측치를 대체했어요. mice 함수는 다양한 imputation 기법을 제공하는 강력한 도구랍니다! method 인자를 통해 원하는 imputation 방법을 지정할 수 있어요. “pmm”(predictive mean matching)은 예측값을 기반으로 결측치를 대체하는 방법 중 하나인데, 특히 연속형 변수에 효과적이라고 알려져 있죠.

결측치 처리는 데이터 분석의 중요한 단계 중 하나이며, 다양한 방법과 기법들이 존재해요. 각 기법의 장단점을 이해하고 데이터의 특성에 맞는 적절한 방법을 선택하는 것이 중요하답니다. 꾸준히 공부하고 연습하다 보면 어떤 상황에서 어떤 방법을 사용해야 할지 감을 잡을 수 있을 거예요! 화이팅! 😄

 

다양한 결측치 처리 방법 비교

휴~, 결측치 확인하고 제거하는 방법까지 알아봤으니 이제 좀 뭔가 감이 잡히시죠? ^^ 하지만! 아직 끝이 아니랍니다! 결측치를 처리하는 방법은 생각보다 훨씬 다양하고, 상황에 따라 적절한 방법을 선택하는 것이 정말 중요해요. 마치 요리할 때 재료에 따라 다른 조리법을 쓰는 것과 같다고나 할까요? 자, 그럼 각각의 방법들을 꼼꼼히 비교해보면서 어떤 상황에 어떤 방법을 써야 하는지 콕콕 집어 드릴게요!

`na.omit()` 함수

자, 우선 가장 기본적인 방법부터 살펴볼까요? na.omit() 함수! 이 친구는 데이터 프레임에서 NA가 포함된 행 전체를 싹~ 날려버리는 아주 강력한 친구예요. 마치 잡초를 뽑듯이 말이죠! 데이터의 양이 충분하고, 결측치가 전체 데이터에서 차지하는 비율이 적을 때 (예를 들어 1~5% 정도?) 유용하게 쓸 수 있어요. 하지만!! 결측치가 너무 많으면 데이터 손실이 커지니까 조심해야 해요! 😱 마치 과일 껍질을 너무 두껍게 깎으면 먹을 게 없어지는 것과 같은 이치죠?

`na.rm = TRUE` 옵션

그럼 결측치가 많을 때는 어떻게 해야 할까요? 🤔 바로 na.rm = TRUE 옵션을 활용하는 거죠! 이 옵션은 sum(), mean() 같은 함수를 사용할 때 결측치를 제외하고 계산하도록 지시하는 역할을 해요. 예를 들어, mean(data$height, na.rm = TRUE)라고 쓰면, data$height 변수에서 NA를 제외한 값들의 평균을 계산해준답니다. 데이터 손실 없이 원하는 계산을 할 수 있다는 장점이 있지만, 결측치가 너무 많으면 결과의 신뢰도가 떨어질 수 있다는 점도 잊지 마세요! 🧐

대체(Imputation) 기법

na.omit()이나 na.rm = TRUE는 간단하고 편리하지만, 때로는 너무 단순한 해결책일 수도 있어요. 결측치가 발생한 이유나 패턴을 고려하지 않고 무작정 제거하거나 무시하는 것은 위험할 수 있거든요. 마치 감기에 걸렸는데 증상만 없애려고 진통제만 먹는 것과 같다고 할까요? 원인을 제대로 파악하고 치료해야 완전히 낫는 것처럼, 결측치도 마찬가지랍니다!

그래서 등장하는 것이 바로 대체(Imputation) 기법입니다! 😎 대체 기법은 결측치를 다른 값으로 채워 넣는 방법이에요. 가장 흔하게 사용되는 방법은 평균값, 중앙값, 최빈값 등으로 대체하는 거예요. 예를 들어, 키 데이터에 결측치가 있다면 전체 키의 평균값으로 채워 넣는 거죠! 간단하고 직관적이지만, 데이터의 분포를 왜곡시킬 수 있다는 단점도 있어요. 특히 결측치가 많을 경우에는 더욱 주의해야 한답니다!

회귀 분석/K-NN 활용

좀 더 정교한 대체 기법으로는 회귀 분석이나 K-최근접 이웃(K-NN) 알고리즘을 활용하는 방법도 있어요. 회귀 분석은 다른 변수들과의 관계를 이용해서 결측치를 예측하는 방법이고, K-NN은 결측치와 가장 유사한 데이터들을 찾아서 그 값들을 기반으로 결측치를 추정하는 방법이에요. 이러한 방법들은 데이터의 특성을 반영하여 보다 정확한 대체 값을 생성할 수 있지만, 계산 비용이 많이 들고 복잡하다는 단점이 있어요. 😅

다중 대체(Multiple Imputation) 기법

자, 이제 마지막으로! 좀 더 고급진 기법을 소개해 드릴게요. 바로 다중 대체(Multiple Imputation) 기법입니다! 🎉 이 기법은 결측치를 한 번만 대체하는 것이 아니라 여러 번 대체하여 여러 개의 완전한 데이터셋을 생성하는 방법이에요. 각각의 데이터셋을 분석한 후 결과를 통합하여 최종 결과를 도출하는데, 이를 통해 결측치로 인한 불확실성을 줄이고 분석 결과의 정확도를 높일 수 있답니다! 하지만, 역시나 계산 비용이 많이 들고 복잡하다는 단점이 있어요. 하지만 그만큼 효과는 확실하다는 거! 👍

결론

결측치 처리 방법, 정말 다양하죠? 어떤 방법을 선택할지는 데이터의 특성, 결측치의 발생 메커니즘, 분석 목적 등을 종합적으로 고려해서 결정해야 해요. 어떤 방법이든 장단점이 있으니, 상황에 맞는 최적의 방법을 찾는 것이 중요하답니다! 마치 옷을 고르듯이 말이죠! 😉 이제 여러분도 R을 이용해서 결측치를 멋지게 처리할 수 있겠죠? 😄 다음에는 더욱 흥미로운 주제로 찾아올게요! 그때까지 R과 함께 즐거운 데이터 분석 시간 보내세요! 🤗

 

R로 데이터 분석하는 여정, 결측치 때문에 힘드셨죠? 이제 걱정 뚝! `is.na()`로 결측치를 확인하고, `na.omit()`으로 제거하고, `na.rm = TRUE`로 계산까지 깔끔하게 할 수 있다는 사실, 이제 잊지 않으실 거예요. 각 방법의 특징을 잘 이해해서 상황에 맞게 활용하면 분석 결과의 정확도도 훨씬 높아질 거예요. 처음엔 조금 헷갈릴 수 있지만, 연습하다 보면 금방 익숙해질 거예요. 혹시라도 궁금한 점이 생기면 언제든 질문해주세요! 다음에는 더 재밌는 R 이야기로 찾아올게요! 분석 실력 쑥쑥 키워서 데이터 마법사가 되는 그날까지, 함께 나아가요!

 

Itlearner

Share
Published by
Itlearner

Recent Posts

R에서 데이터 정렬 (order(), arrange())

안녕하세요! 데이터 분석하면서 정렬 때문에 골치 아팠던 적, 다들 한 번쯤 있으시죠? 저도 그랬어요. 그래서…

3시간 ago

R에서 apply 계열 함수 (apply(), sapply(), lapply(), tapply())

R 언어를 다루다 보면, 반복적인 작업을 효율적으로 처리하고 싶을 때가 많죠? 그럴 때 엄청 유용한…

13시간 ago

R에서 함수(Function) 정의 및 호출 (function() { })

안녕하세요, 여러분! 오늘은 R과 친해지기 위한 아주 중요한 걸음을 함께 내딛어 보려고 해요. 바로 함수(function)…

17시간 ago

R에서 반복문 (for, while, repeat 활용법)

R 언어로 데이터 분석을 하다 보면, 반복 작업이 정말 많죠? 그럴 때마다 일일이 코드를 반복해서…

21시간 ago

R에서 제어문 (if-else, switch)

안녕하세요, 여러분! 오늘은 R과 함께 신나는 코딩 여행을 떠나볼까요? R을 이용하면 데이터 분석이 정말 재밌어져요!…

1일 ago

R에서 산술 연산자 및 논리 연산자 (+, -, *, ==, !=, &, |)

안녕하세요, 여러분! 😊 오늘은 R과 함께 신나는 데이터 분석 여행을 떠나볼까요? 데이터 분석에서 가장 기본적이면서도…

1일 ago