결측값을 다루는 것은 데이터를 다루는데 있어 매우 중요한 요소입니다. 동시에 매우 곤란한 문제가 될수도 있습니다. 아무튼 결측값이나 이상치는 항상 생길 수밖에 없고 데이터를 분석하는 한 이를 어떻게 해결할지를 고민해야 합니다. 일단 오늘은 결측값을 특정값으로 대체하거나 혹은 특정값을 결측값으로 대체하는 예제를 설명해보겠습니다.
우선 앞서 많이 사용했던 다이아몬드 데이터 셋에 결측값이 있는지를 알아보겠습니다. 보통 결측값을 알아보는 명령어는 is.na 입니다. 하지만 데이터 셋이 크면 상당히 불편한 명령어입니다. library("ggplot2")로 다이아몬드 데이터를 불러들인 후 is.na 명령어를 확인해 보겠습니다.
FALSE라는 내용을 쭉 출력하는데, 관측값이 몇 만개나 되면 도저히 일일이 확인이 불가능합니다. 보통 우리가 알고 싶은 것은 결측값의 갯수일 것입니다. 앞서 소개한 summary() 명령어로 결측치의 갯수를 확인할 수 있는데, 다른 값까지 같이 출력되므로 결측값만 보려면 sum(is.na())를 사용합니다.
sum(is.na(diamonds))
[1] 0
다이아몬드 데이터는 결측값이 없는 데이터입니다. 그런데 그렇게 되면 더 이상 이야기를 진행할 수 없으므로 결측값을 만들어보겠습니다. 다이아몬드 데이터에서 컷 (Cut)이 Good 경우를 결측값으로 대체해 보겠습니다. R의 기본 함수인 replace를 사용하겠습니다.
replace(diamonds$cut,diamonds$cut=="Good",NA)->diamonds$cut
기본 문법은 replace () 안에 (바꾸려고 하는 변수, 바꾸려는 조건, 변경된 내용(여기서는 결측값 (NA)) 를 쓰는 것입니다. 그런데 이 함수는 데이터 프레임 자체를 바꾸지 않기 때문에 여기서 -> 표시후 변수를 표시해서 내용을 바꾼다는 점을 표시를 해주는 것입니다. head 혹은 summary 를 이용해서 결측값으로 제대로 변경된 것을 볼 수 있습니다.
앞서 포스트에서 설명한 것처럼 R 은 기본적으로 결측값을 빼고 계산을 합니다. na.omit를 이용해서 결측값을 모두 제거할 수 있습니다. na.omit(diamonds)를 이용해서 결측값을 모두 빼버리는 것이죠. 참고로 앞서와 반대 방법으로 cut에 999나 0을 넣으려고 하면 안될 것입니다. 본래 범주형 변수로 정해져 있기 때문이죠. 반면 Good이라고 다시 넣는 것은 가능합니다. 다만 아래처럼 하면 실제로는 변경이 안됩니다.
> replace(diamonds$cut,diamonds$cut=="NA","Good")->diamonds$cut
> head(diamonds)
# A tibble: 6 × 10
carat cut color clarity depth table price x y z
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
3 0.23 NA E VS1 56.9 65 327 4.05 4.07 2.31
4 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
5 0.31 NA J SI2 63.3 58 335 4.34 4.35 2.75
6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
이는 결측값을 다루는 방법 때문인 것 같습니다. 여기서는 결측값이라는 의미의 is.na 함수를 사용해야 합니다.
> diamonds$cut[is.na(diamonds$cut)]<- ood="" span="">->
> head(diamonds)
# A tibble: 6 × 10
carat cut color clarity depth table price x y z
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
4 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
변수명[is.na(변수명)] <- span="">->
이번에는 1캐럿 이상의 다이아몬드를 모두 결측치로 처리해 보겠습니다.
replace(diamonds$carat,diamonds$carat>1,NA)->diamonds$carat
결측치는 종종 999 같은 값으로 입력됩니다. 이는 데이터 입력을 위한 것입니다. (입력 하지 않은 경우와 결측치를 구분하기 위한 방법입니다) 하지만 데이터 분석시에는 필요없기 때문에 다시 결측치로 돌려야 합니다. 여기서는 반대로 결측치에 999를 입력하고 다시 결측치로 바꿔보겠습니다. 역시 is.na를 이용합니다.
diamonds$carat[is.na(diamonds$carat)]<-999 span="">-999>
정상적으로 되었는지를 확인하려면 summary(diamonds)를 이용해서 결측치의 종류와 숫자를 확인합니다. 다시 999를 결측치로 넣으려면 replace 함수를 사용해도 되지만 아래처럼 하는 것이 더 간단할 수도 있습니다.
diamonds$carat[diamonds$carat==999]<-na span="">-na>
제대로 되었는지는 summary () 함수로 확인합니다. 일단 결측치에 대한 질문이 많아서 결측치에 대한 이야기를 더 진행하고 다음 과제로 넘어가겠습니다.
댓글
댓글 쓰기