필요에 의해서 구현한 R 결측치 채우는 함수

어떤 데이터든 실무에서는 결측치에 대한 전략이 있어야 한다. 그리고 이에대한 적절한 처리 후 데이터 분석에 들어 가야 한다.

물론 다양한 결측치 채우기 전략이 있을 수 있는데, 여기서는 간단하게 중앙값, 평균, 그리고 모드(mode)를 이용하고, 적절하게 숫자형, 범주형데이터를 모두 처리한다.

해당 리스트에서 결측치가 존재할 경우 정규성 테스트를 한 이후 0.05유의 수준에 따라 정규분포를 하고 있다면 평균값을 구해 그 값으로 결측치를 채우고 아니라면 중앙값으로 채운다.

중앙값으로 채우는 이유는 샘플이 정규분포를 하지 않는다면 평균이 대표성을 띄기 어렵기 때문이다.

그리고 factor라고 불리우는 범주형 값들에는 가장 많은 빈도수를 가지는 값을 넣어주면 될 것이다.

 

아래는 Weka의 Soybean 데이터를 가지고 결측치를 채우는 예제이다.

#Weka에 있는 Soybean 예제를 읽어 온다. 
soybean <- read.arff("c:/program files/Weka-3-6/data/soybean.arff")   #getCentral 함수로 숫자형 벡터일 경우 shapiro test를 거쳐 normality 테스트 후 샘플이 정규분포
#를 하고 있다면 평균값을 구하고 그렇지 않다면 중앙값을 구한다. 
#만일 범주형 factor 값이라면 가장 빈번한 값인 mode를 구해서 이를 대표값으로 리턴한다. 
getCentral <- function(vec){
	if(is.numeric(vec)){
		if(shapiro.test(vec)$p.value > 0.05){
			median(vec, na.rm=TRUE)
		}else
			mean(vec, na.rm=TRUE)
	}else if(is.factor(vec)){
		vectab <- table(vec)
		vecmode <- names(which(vectab == max(vectab)))
		if(length(vecmode)){
			return(vecmode[1])
		}
	}else{
		warning("check vec type!")
	}
}   #soybean$`seed-tmt`변수의 결측치들을 대표값으로 채운다. 
soybean[is.na(soybean$`seed-tmt`), "seed-tmt"] <- getCentral(soybean$`seed-tmt`)

Created by Pretty R at inside-R.org

 

샘플의 개수가 5000개가 넘어가면 shapiro test는 신뢰성 있는 값을 넘겨주지 못하니 주의를 요한다.

이 방법 이외에 가장 비슷한 경향을 가지는 변수를 기반으로 결측치를 예측하는 방법도 있고, 가장 비슷한 레코드를 가져와 그 레코드의 값으로 채우는 방법도 있다.

모두 장,단점이 있으니 이것저것 사용해보고 상황에 맞는 취사 선택이 필요할 것이다.