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

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

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

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

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

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

 

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

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

Created by Pretty R at inside-R.org

 

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

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

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

CC BY-NC 4.0 필요에 의해서 구현한 R 결측치 채우는 함수 by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.