獨斷論

통계 R 사용설명서 9 - 결측값(missing values) 처리방법 본문

과학과 기술/R 통계

통계 R 사용설명서 9 - 결측값(missing values) 처리방법

부르칸 2016. 5. 10. 07:48

결측값(missing values)이란 측정한 데이터 중에 몇몇 변수들의 값이 측정되지 못한 경우를 말한다.

R에서는 이 변수값들은 보통 NA라고 표기한다. NA는 not available을 의미한다.

예를 들어 변수 y에 5개의 값 중에 1개가 결측값일때 

 > y <- c(1, 5, 3, NA, 6)

 

라고 입력이 가능하다. 또한 어떤 원소에 결측값이 존재하는지 알려면 is.na()를 사용하면 된다.

 > is.na(y)
 [1] FALSE FALSE FALSE  TRUE FALSE

결과값에서 TRUE인 원소가 결측값이 있는 것이다.

이제 좀더 실제 데이터와 비슷한 예를 들어보자.

참가자 8명에게 5가지 질문을 하여 1부터 10까지 대답하게 하였다고 가정한다면

 > id <- c('s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8')
 > q1 <- c(10, 3, 5, 8, 4, 7, 3, 6)
 > q2 <- c(7, NA, 4, 5, 9, 10, 1, 9)
 > q3 <- c(9, NA, 8, 9, 9, 4, NA, 8)
 > q4 <- c(8, 6, 10, 4, 5, 2, 9, 10)
 > q5 <- c(3, 6, 8, 3, 5, 4, 6, 8)
 > mydat <- data.frame(id, q1, q2, q3, q4, q5, stringAsFactors = FALSE)
 > mydat
   id q1 q2 q3 q4 q5 stringAsFactors
 1 s1 10  7  9  8  3           FALSE
 2 s2  3 NA NA  6  6           FALSE
 3 s3  5  4  8 10  8           FALSE
 4 s4  8  5  9  4  3           FALSE
 5 s5  4  9  9  5  5           FALSE
 6 s6  7 10  4  2  4           FALSE
 7 s7  3  1 NA  9  6           FALSE
 8 s8  6  9  8 10  8           FALSE

1번 줄에서 참가자 id를 입력하였고

2~6번 줄에서 5가지 질문에 대한 8명 참가자의 대답을 입력하였다.

이들 데이터를 7번 줄에서 data frame으로 변수변환을 하였고 그결과가 9~17번째 줄에 나타나있다.

여기서 NA로 코딩된 것들은 결측값(missing values)를 의미한다.

 

역시 어느 데이터변수에 결측값이 존재하는지 알려면 is.na()를 사용한다.

 > is.na(mydat[, 2:6])
         q1    q2    q3    q4    q5
 [1,] FALSE FALSE FALSE FALSE FALSE
 [2,] FALSE  TRUE  TRUE FALSE FALSE
 [3,] FALSE FALSE FALSE FALSE FALSE
 [4,] FALSE FALSE FALSE FALSE FALSE
 [5,] FALSE FALSE FALSE FALSE FALSE
 [6,] FALSE FALSE FALSE FALSE FALSE
 [7,] FALSE FALSE  TRUE FALSE FALSE
 [8,] FALSE FALSE FALSE FALSE FALSE

 

결측값 리코딩(Recoding)

 

경우에 따라 결측값을 -9999같은 값으로 측정되기도 하는데 이런 데이터를 R에서 사용하려면 이들 값들을 NA로 리코딩해야한다.

 

아래 스크립드에서 결측값을 -9999라고 직접 console에서 코딩하였지만

보통 이는 텍스트 파일로 존재하는 데이터 파일로부터 읽어들인다.

여기서는 간단한 예제이므로 데이터 값을 console에 직접 c( )함수를 이용하였다.

 > id <- c('s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8')
 > q1 <- c(10, 3, 5, 8, 4, 7, 3, 6)
 > q2 <- c(7, -9999, 4, 5, 9, 10, 1, 9)
 > q3 <- c(9, -9999, 8, 9, 9, 4, -9999, 8)
 > q4 <- c(8, 6, 10, 4, 5, 2, 9, 10)
 > q5 <- c(3, 6, 8, 3, 5, 4, 6, 8)
 > mydat <- data.frame(id, q1, q2, q3, q4, q5, stringAsFactors = FALSE)
 > mydat
   id q1    q2    q3 q4 q5 stringAsFactors
 1 s1 10     7     9  8  3           FALSE
 2 s2  3 -9999 -9999  6  6           FALSE
 3 s3  5     4     8 10  8           FALSE
 4 s4  8     5     9  4  3           FALSE
 5 s5  4     9     9  5  5           FALSE
 6 s6  7    10     4  2  4           FALSE
 7 s7  3     1 -9999  9  6           FALSE
 8 s8  6     9     8 10  8           FALSE

이제 -9999로 된 결측값을 NA로 recoding해보자.

 > mydat[mydat == -9999] <- NA
 > mydat
   id q1 q2 q3 q4 q5 stringAsFactors
 1 s1 10  7  9  8  3           FALSE
 2 s2  3 NA NA  6  6           FALSE
 3 s3  5  4  8 10  8           FALSE
 4 s4  8  5  9  4  3           FALSE
 5 s5  4  9  9  5  5           FALSE
 6 s6  7 10  4  2  4           FALSE
 7 s7  3  1 NA  9  6           FALSE
 8 s8  6  9  8 10  8           FALSE

 

 

분석할때 결측값 자동으로 제외하기

  • na.rm 옵션을 이용하기

na.rm =  TRUE를 이용하여 분석할때 결측값이 있는 subject 또는 observation을 제외시킬수 있다.

 > q2_sum <- sum(mydat$q2)
 > q2_sum
 [1] NA
 > q2_sum <- sum(mydat$q2, na.rm = TRUE)
 > q2_sum
 [1] 45

mydatq2변수는 결측값을 가지고 있으므로 sum()을 이용하여 모두 더하면 그 결과가 NA가 된다.

하지만 na.rm = TRUEsum()의 옵션으로 이용하면 45라는 결과를 얻을수 있다.

그런데 이상하게도 모든 함수에서 이런 na.rm = TRUE를 허락하는 것이 아니다. 만약 자신이 사용하고자 하는 함수가 na.rm=TRUE를 허용하지 않는다면 데이터에서 완전히 그 행을 삭제하는 것이 가능하다. 자신이 사용하고자 하는 함수가 na.rm을 사용할수 있는지 없는지 알려고 하려면 help(sum)과 같이 help( )의 괄호 안에 자신이 사용하고자 하는 함수명을 치면 된다.

 

  • 데이터에서 완전히 삭제하기

결측값이 존재하는 행을 완전히 삭제하여 새로운 변수에 저장하여 분석하는 것도 가능하다.

na.omit()을 사용한다.

> mydat
   id q1 q2 q3 q4 q5 stringAsFactors
 1 s1 10  7  9  8  3           FALSE
 2 s2  3 NA NA  6  6           FALSE
 3 s3  5  4  8 10  8           FALSE
 4 s4  8  5  9  4  3           FALSE
 5 s5  4  9  9  5  5           FALSE
 6 s6  7 10  4  2  4           FALSE
 7 s7  3  1 NA  9  6           FALSE
 8 s8  6  9  8 10  8           FALSE
 > mydat1 <- na.omit(mydat)
 > mydat1
   id q1 q2 q3 q4 q5 stringAsFactors
 1 s1 10  7  9  8  3           FALSE
 3 s3  5  4  8 10  8           FALSE
 4 s4  8  5  9  4  3           FALSE
 5 s5  4  9  9  5  5           FALSE
 6 s6  7 10  4  2  4           FALSE
 8 s8  6  9  8 10  8           FALSE
 > q2_sum <- sum(mydat1$q2)
 > q2_sum
 [1] 44

s2와 s7에 결측값이 존재하므로 이 행들을 모두 삭제하여 mydat1에 저장하였다.

주의할 것은 q2의 합을 구할때 s7의 q2는 결측값이 아님에도 불구하고 s7이 삭제되었다는 것을 명심해야한다.

 

 

 

 

 

 

 

Comments