6 분 소요


※ 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

댓글남기기