Programing/R- programming

결측치 NA (Missing value) 연산 / R programming

sosal 2014. 8. 21. 11:34
반응형

/*

 http://sosal.kr/
 * made by so_Sal
 */


R 프로그래밍에서 결측지(missing value)는 NA (Not Available) 라는 문자로 처리해야 한다.

NaN (Not a Number)는 분모를 0으로 나누는 것과 같이 계산이 불가능 할 경우 출력되는 문자다.


> y <- c(1,2,3, NA)

> y

[1]  1  2  3 NA


is.na()는 벡터의 결측지가 존재할 경우 true

> is.na(y)

[1] FALSE FALSE FALSE  TRUE


> summary(y)

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 

    1.0       1.5       2.0       2.0       2.5       3.0         1 


NA는 missing value를 표현하는 논리형 자료이지만, "NA"는 문자열 그 자체이다.

> is.na( NA )

[1] TRUE

> is.na( "NA" )

[1] FALSE





특정 값을 NA로 바꾸기 (-999 -> NA )

> ages <- c(48, 78, 56, 88, -999, 13, 26, -999)

> ages[ ages == -999] <- NA

> ages

[1] 48 78 56 88 NA 13 26 NA



결측지(missing value)가 하나라도 포함된 데이터가 존재할 경우 연산의 결과 역시 NA가 된다.

따라서 함수 역시 아래와 같이 NA가 결과로 나온다.

> sum(ages)

[1] NA

> mean(ages)

[1] NA


NA 데이터를 제외하고 연산하고 싶을 경우  na.rm = TRUE 매개변수를 넣어주면 된다.



> sum(ages, na.rm = TRUE)

[1] 309

> mean(ages, na.rm=TRUE)

[1] 51.5







대부분의 함수에서는 위의 예제처럼 na.rm이라는 매개변수가 존재하여 NA 데이터를 무시하고 연산할 수 있지만, 결측치가 존재할 경우 아예 연산할 수 없는 함수들도 있다. 그런경우 결측지가 있는 row 자체를 제거해야 될 수도 있을것이다.


다음의 예제로 실습해보자.




실습예제)


> weight <- c(65.4, 55, 380, 72.2, 51, NA)

> height <- c(170, 155, NA, 173, 161, 166)

> gender <- c("M", "F","M","M","F","F")

> testDate <- c("2013/09/01", "2013/09/01", "2013/09/05", "2013/09/14", "2013/10/11", "2013/10/26")

> patients <- data.frame( weight = weight, height=height, gender=gender, testDate=testDate)

> patients

  weight height gender   testDate

1   65.4    170      M 2013/09/01

2   55.0    155      F 2013/09/01

3  380.0    NA      M 2013/09/05

4   72.2    173      M 2013/09/14

5   51.0    161      F 2013/10/11

6    NA    166      F 2013/10/26


> str(patients)

'data.frame':   6 obs. of  4 variables:

 $ weight  : num  65.4 55 380 72.2 51 NA

 $ height  : num  170 155 NA 173 161 166

 $ gender  : Factor w/ 2 levels "F","M": 2 1 2 2 1 1

 $ testDate: Factor w/ 5 levels "2013/09/01","2013/09/05",..: 1 1 2 3 4 5



몸무게 측정을 거부한 환자 (6), 키 측정을 거부한 환자 (3)를 제외한 환자들 목록을 부르기

> na.omit(patients) # 해당 row 데이터를 삭제한 후 출력하는 방법

  weight height gender   testDate

1   65.4    170      M 2013/09/01

2   55.0    155      F 2013/09/01

4   72.2    173      M 2013/09/14

5   51.0    161      F 2013/10/11


> complete.cases(patients) # NA가 존재하는 경우 FALSE를 리턴

[1]  TRUE  TRUE FALSE  TRUE  TRUE FALSE


> patients[complete.cases(patients),] # complete.cases 함수 리턴값이 참인 경우를 출력하는 방법

  weight height gender   testDate

1   65.4    170      M 2013/09/01

2   55.0    155      F 2013/09/01

4   72.2    173      M 2013/09/14

5   51.0    161      F 2013/10/11




patients 데이터에서 weight, height만 가져오기

> patients.sub <- patients[ ,c("weight","height")]

> patients.sub

  weight height

1   65.4    170

2   55.0    155

3  380.0     NA

4   72.2    173

5   51.0    161

6     NA    166



patients.sub 데이터 연산하기

> apply(patients.sub, 2, mean) # patients.sub 데이터에 2: 열단위, mean 함수 적용

weight height 

    NA     NA 


NA 데이터 삭제한 후 연산하기

> apply(patients.sub, 2, mean, na.rm=TRUE)

weight height 

124.72 165.00 




환자 데이터 날짜를 실제 date 형태로 계산하기

> patients

  weight height gender   testDate

1   65.4    170      M 2013/09/01

2   55.0    155      F 2013/09/01

3  380.0     NA      M 2013/09/05

4   72.2    173      M 2013/09/14

5   51.0    161      F 2013/10/11

6     NA    166      F 2013/10/26

> patients$testDate <- as.Date(testDate)

> patients

  weight height gender   testDate

1   65.4    170      M 2013-09-01

2   55.0    155      F 2013-09-01

3  380.0     NA      M 2013-09-05

4   72.2    173      M 2013-09-14

5   51.0    161      F 2013-10-11

6     NA    166      F 2013-10-26


2013/09/01 -> 2013-09-01 형태로 바뀜


> patients$testDate[5] - patients$testDate[1]

Time difference of 40 days

> as.numeric(patients$testDate[5] - patients$testDate[1])

[1] 40

날짜연산 가능