NA handling in R (결측치 처리하기)
※ NA handling (결측치 처리)
◎ 사용할 패키지: tidyverse
library(tidyverse)
◎ 예시 Data (df)
name class math eng gender
1 Hwayoung 1 74.0 76 f
2 <NA> 2 56.0 70 <NA>
3 Sua 3 63.7 77 <NA>
4 Sojin 2 57.0 68 <NA>
5 Minjeong 3 42.0 NA <NA>
6 Gaeun 1 39.0 63 <NA>
7 Janghoon 1 55.0 70 m
8 Sunghoon 2 68.0 NA <NA>
9 Jaeyoung 3 63.7 95 <NA>
10 Yeseung 3 83.0 NA <NA>
11 Jungjae 2 92.0 100 <NA>
12 Kyunghwan 2 71.0 65 <NA>
◎ 예시 Data (df2)
name class math eng gender
1 Hwayoung 1 74 76 f
2 <NA> 2 56 70 <NA>
3 Sua 3 NA 77 <NA>
4 Sojin 2 57 68 <NA>
5 Minjeong 3 42 NA <NA>
6 Gaeun 1 39 63 <NA>
7 Janghoon 1 55 70 m
8 Sunghoon 2 68 NA <NA>
9 Jaeyoung 3 NA 95 <NA>
10 Yeseung 3 83 NA <NA>
11 Jungjae 2 92 100 <NA>
12 Kyunghwan 2 71 65 <NA>
■ NA 여부 체크
□ anyNA이용
> anyNA(df)
[1] TRUE
□ is.na이용
> is.na(df)
name class math eng
[1,] FALSE FALSE FALSE FALSE
[2,] TRUE FALSE FALSE FALSE
[3,] FALSE FALSE TRUE FALSE
[4,] FALSE FALSE FALSE FALSE
[5,] FALSE FALSE FALSE TRUE
[6,] FALSE FALSE FALSE FALSE
[7,] FALSE FALSE FALSE FALSE
[8,] FALSE FALSE FALSE TRUE
[9,] FALSE FALSE TRUE FALSE
[10,] FALSE FALSE FALSE TRUE
[11,] FALSE FALSE FALSE FALSE
[12,] FALSE FALSE FALSE FALSE
□ table이용
Data에 NA가 몇개 있는지 (TRUE 값)
> table(is.na(df))
FALSE TRUE
42 6
□ **colSums **이용
각 컬럼별 NA 개수 보기
> df %>% is.na %>% colSums())
> colSums(is.na(df))
name class math eng
1 0 2 3
■ NA 제거
□ na.omit
NA가 포함된 모든 Data를 지울 수 있지만, 너무 많은 Data가 삭제될 수 있음
> na.omit(df2)
name class math eng gender
1 Hwayoung 1 74 76 f
7 Janghoon 1 55 70 m
□ filter
# 수학 점수가 NA인 경우
> df %>%
+ filter(is.na(math))
name class math eng
1 Sua 3 NA 77
2 Jaeyoung 3 NA 95
# 수학 점수가 NA가 아닌 경우
> df %>%
+ filter(!is.na(math))
name class math eng
1 Hwayoung 1 74 76
2 <NA> 2 56 70
3 Sojin 2 57 68
4 Minjeong 3 42 NA
5 Gaeun 1 39 63
6 Janghoon 1 55 70
7 Sunghoon 2 68 NA
8 Yeseung 3 83 NA
9 Jungjae 2 92 100
10 Kyunghwan 2 71 65
# 수학과 영어 점수가 NA가 아닌 경우
> df %>%
+ filter(!is.na(math) & !is.na(eng))
name class math eng
1 Hwayoung 1 74 76
2 <NA> 2 56 70
3 Sojin 2 57 68
4 Gaeun 1 39 63
5 Janghoon 1 55 70
6 Jungjae 2 92 100
7 Kyunghwan 2 71 65
□ drop_na
> df %>%
+ drop_na()
name class math eng
1 Hwayoung 1 74 76
2 Sojin 2 57 68
3 Gaeun 1 39 63
4 Janghoon 1 55 70
5 Jungjae 2 92 100
6 Kyunghwan 2 71 65
df %>%
drop_na(math)
df %>%
drop_na(math,eng)
#NA를 제거한 Data의 수학과 영어 평균점수
d> df2 %>%
+ drop_na(math, eng) %>%
+ group_by(class) %>%
+ summarize(mean(math), mean(eng))
# A tibble: 2 × 3
class `mean(math)` `mean(eng)`
<dbl> <dbl> <dbl>
1 1 56 69.7
2 2 69 75.8
□ na.rm
> df2 %>%
+ summarize(mean(math, na.rm=T))
mean(math, na.rm = T)
1 63.7
■ NA 대체
□ NA를 제외한 평균, 중위수, 최빈값 등을 이용
df$math[is.na(df$math)] <- mean(df$math, na.rm = T)
□ fill함수 이용
바로 위에 있는 값들로 채움
> df2 %>%
+ fill(math)
name class math eng gender
1 Hwayoung 1 74 76 f
2 <NA> 2 56 70 <NA>
3 Sua 3 56 77 <NA>
4 Sojin 2 57 68 <NA>
5 Minjeong 3 42 NA <NA>
6 Gaeun 1 39 63 <NA>
7 Janghoon 1 55 70 m
8 Sunghoon 2 68 NA <NA>
9 Jaeyoung 3 68 95 <NA>
10 Yeseung 3 83 NA <NA>
11 Jungjae 2 92 100 <NA>
12 Kyunghwan 2 71 65 <NA>
> df2 %>%
+ fill(gender, .direction = "down")
name class math eng gender
1 Hwayoung 1 74 76 f
2 <NA> 2 56 70 f
3 Sua 3 NA 77 f
4 Sojin 2 57 68 f
5 Minjeong 3 42 NA f
6 Gaeun 1 39 63 f
7 Janghoon 1 55 70 m
8 Sunghoon 2 68 NA m
9 Jaeyoung 3 NA 95 m
10 Yeseung 3 83 NA m
11 Jungjae 2 92 100 m
12 Kyunghwan 2 71 65 m
□ replace_na이용
#NA를 0값으로 대체
> df2 %>%
+ replace_na(list(math = 0))
name class math eng gender
1 Hwayoung 1 74 76 f
2 <NA> 2 56 70 <NA>
3 Sua 3 0 77 <NA>
4 Sojin 2 57 68 <NA>
5 Minjeong 3 42 NA <NA>
6 Gaeun 1 39 63 <NA>
7 Janghoon 1 55 70 m
8 Sunghoon 2 68 NA <NA>
9 Jaeyoung 3 0 95 <NA>
10 Yeseung 3 83 NA <NA>
11 Jungjae 2 92 100 <NA>
12 Kyunghwan 2 71 65 <NA>
#수학은 0점, 영어는 10점으로 대체
> df2 %>%
+ replace_na(list(math = 0, eng = 10))
name class math eng gender
1 Hwayoung 1 74 76 f
2 <NA> 2 56 70 <NA>
3 Sua 3 0 77 <NA>
4 Sojin 2 57 68 <NA>
5 Minjeong 3 42 10 <NA>
6 Gaeun 1 39 63 <NA>
7 Janghoon 1 55 70 m
8 Sunghoon 2 68 10 <NA>
9 Jaeyoung 3 0 95 <NA>
10 Yeseung 3 83 10 <NA>
11 Jungjae 2 92 100 <NA>
12 Kyunghwan 2 71 65 <NA>
# NA값을 수학평균점수로 대체
# mean에 $로 컬럼명 지정해야함
> df2 %>%
+ replace_na(list(math = mean(df2$math, na.rm = T)))
name class math eng gender
1 Hwayoung 1 74.0 76 f
2 <NA> 2 56.0 70 <NA>
3 Sua 3 63.7 77 <NA>
4 Sojin 2 57.0 68 <NA>
5 Minjeong 3 42.0 NA <NA>
6 Gaeun 1 39.0 63 <NA>
7 Janghoon 1 55.0 70 m
8 Sunghoon 2 68.0 NA <NA>
9 Jaeyoung 3 63.7 95 <NA>
10 Yeseung 3 83.0 NA <NA>
11 Jungjae 2 92.0 100 <NA>
12 Kyunghwan 2 71.0 65 <NA>
□ mutate이용
# NA값을 수학평균점수로 대체
> df2 %>%
+ mutate(math = ifelse(is.na(math), mean(math, na.rm = T), math))
name class math eng gender
1 Hwayoung 1 74.0 76 f
2 <NA> 2 56.0 70 <NA>
3 Sua 3 63.7 77 <NA>
4 Sojin 2 57.0 68 <NA>
5 Minjeong 3 42.0 NA <NA>
6 Gaeun 1 39.0 63 <NA>
7 Janghoon 1 55.0 70 m
8 Sunghoon 2 68.0 NA <NA>
9 Jaeyoung 3 63.7 95 <NA>
10 Yeseung 3 83.0 NA <NA>
11 Jungjae 2 92.0 100 <NA>
12 Kyunghwan 2 71.0 65 <NA>
□ 모델을 활용한 NA값 보완
> amelia(data, m = NA 대치가 완료된 데이터 개수)
> amelia_df <- amelia(missing_df, m = 2)
> amelia_df$imputations[[1]] # 결측치 보완이 완료된 첫번째 데이터
> amelia_df$imputations[[2]] # 결측치 보완이 완료된 두번째 데이터
# 결측치 보완이 완료된 데이터들의 평균
final_df <- (amelia_df$imputations[[1]] + amelia_df$imputations[[2]]) / 2
> mice(data, m = NA 대치가 완료된 데이터 개수, method = 결측치 대치 방법)
> complete(mice의 결과, 결측치 보완이 완료된 n번째 데이터)
> mice_df <- mice(missing_df, m = 2)
> complete(mice_df, 1) # 결측치 보완이 완료된 첫번째 데이터
> complete(mice_df, 2) # 결측치 보완이 완료된 두번째 데이터
# 결측치 보완이 완료된 데이터들의 평균
final_df <- (complete(mice_df, 1) + complete(mice_df, 2)) / 2
댓글남기기