본문 바로가기

데이터/R 프로그래밍

R 프로그래밍 기초 (4)

1. 결측치 찾기 

 

결측치(Missing Value)

- 누락된 값

- 결측치가 있으면 함수가 적용되지 않거나 분석 결과가 왜곡되는 문제 발생 

 

1) 결측치가 포함된 데이터 프레임 생성 

 

df<-data.frame(sex=c("M","F",NA,"M","F"),score=c(5,4,3,4,NA))
> 


##  sex score
1    M     5
2    F     4
3 <NA>     3
4    M     4
5    F    NA

 

2) 결측치 확인하기 

 

- is.na()를 이용하면 데이터에 결측치가 들어있는지 알 수 있음 

- is.na()에 df를 적용하면 결측치는 TRUE, 결측치가 아닌 값은 FLASE로 표시해 데이터를 출력

 

is.na(df) #결측치 확인


##     sex score
[1,] FALSE FALSE
[2,] FALSE FALSE
[3,]  TRUE FALSE
[4,] FALSE FALSE
[5,] FALSE  TRUE

 

3) 결측치 빈도 확인 

 

- is.na()를 table()에 적용하면 데이터에 결측치가 총 몇개 있는지 출력 

 table(is.na(df)) #결측치 빈도 출력

##FALSE  TRUE 
    8     2

 

- 결측치를 제거하려면 데이터 전체가 아닌 구체적으로 어떤 변수에 결측치가 있는지 알아야 함

- table(is.na())에 변수명을 지정하면 해당 변수에 결측치가 몇 개 있는지 알 수 있음

 

table(is.na(df$sex)) #sex 결측치 빈도 출력

##FALSE  TRUE 
    4     1 
    table(is.na(df$score)) #score 결측치 빈도 출력

##FALSE  TRUE 
    4     1

 

 

2. 결측치 제거하기 

 

1) 결측치 있는 행 제거 

 

- is.na()를 filter()에 적용하면 결측치가 있는 행을 제거할 수 있음 

- score의 값이 NA인 데이터만 출력

library(dplyr)
> df %>% filter(is.na(score)) #score가 NA인 데이터 출력

##  sex score
1   F    NA

 

- !is.na()는 NA가 아닌값(결측치가 아닌값)을 의미 

- 이 코드를 filter()에 적용하면 결측치를 제외하고 행을 추출 

df %>% filter(!is.na(score))
   sex score
1    M     5
2    F     4
3 <NA>     3
4    M     4

 

2) 결측치가 없는 데이터 프레임 만들기 

 

 df_nomiss<-df %>%  filter(!is.na(score)) ##score, sex 결측치 제거 
 mean(df_nomiss$score) #출력

##[1] 4
 sum(df_nomiss$score)

##[1] 16

 

 

3) 여러 변수 동시에 결측치 없는 데이터 추출하기 

 

- score만 결측치가 없는 행을 추출했기 떄문에 sex는 여전히 결측치를 포함하고 있음

- filter()에 & 기호를 이용해 조건을 나열하면 여러 변수에 모두 결측치가 없는 행을 추출할 수 있음

 

df_nomiss<-df %>% filter(!is.na(score)&!is.na(sex)) ##score, sex 결측치 제거 
df_nomiss


##  sex score
1   M     5
2   F     4
3   M     4

 

4) 결측치가 하나라도 있으면 제거하기 

 

- na.omit()을 이용하면 변수를 지정하지 않고 결측치가 있는 행을 한꺼번에 제거할 수 있음

 df_nomiss2<-na.omit(df) # 모든 변수에 결측치 없는 데이터 추출
df_nomiss2 # 추출
 
## sex score
1   M     5
2   F     4
4   M     4

 

 

3. 함수의 결측치 제외기능 이용하기 

 

- mean()과 같은 수치 연산 함수들은 결측치를 제외하고 연산하도록 설정하는 na.rm 파라미터를 지원 

- na.rm을 TRUE로 설정하면 결측치를 제외하고 함수를 적용하기 때문에 일일이 결측치를 제거하는 절차를 건너뛰고 곧바로 분석할 수 있음 

 

1) na.rm 파라미터 사용

 

mean(df$score,na.rm=T) # 결측치 제외하고 평균 산출

##[1] 4

sum(df$score,na.rm=T) # 결측치 제외하고 합계 산출

##[1] 16

 

2) summrise()를 이용

 

 - csv_exam.csv 파일을 이용해 na.rm을 사용 

 

 exam<-read.csv("csv_exam.csv") # 데이터 불러오기
exam[c(3,8,15),"math"]<-NA # 3,8,15행의 math에 NA 할당
exam


 ##  id class math english science
1   1     1   50      98      50
2   2     1   60      97      60
3   3     1   NA      86      78
4   4     1   30      98      58
5   5     2   25      80      65
6   6     2   50      89      98
7   7     2   80      90      45
8   8     2   NA      78      25

 

- mean()에 na.rm=T를 적용해 결측치를 제외하고 평균 구하기 

 

#math 결측치를 제외하고 평균 산출
exam %>% summarise(mean_math=mean(math,na.rm=T)) 
 
##mean_math
1  55.23529

 

 

4. 결측치 대체하기 

 

결측치 대체법(imputation)

 

 - 결측치를 다른 값으로 대체하면 데이터가 손실되어 분석 결과가 왜곡되는 문제를 보완 

 - 평균이나 최빈값 같은 대표값을 구해 모든 결측치를 하나의 값으로 일괄 대체하는 방법

 - 통계 분석 기법으로 각 결측치의 예측값을 추정해 대체하는 방법 

 

 

1) 평균값으로 결측치 대체하기 

 

- math의 평균값 

mean(exam$math,na.rm=T) # 결측치 제외하고 math 평균 산출

##55.23529

 

- iselse()를 이용해 NA값을 평균값으로 대체 

- math가 NA이면 55를 부여하고 그렇지 않으면 원래의 값을 부여 

exam$math<-ifelse(is.na(exam$math),55,exam$math) #math가 NA면 55로 대체 
table(is.na(exam$math)) # 결측치 빈도표 생성

##FALSE 
##   20 

exam #출력

 ##  id class math english science
1   1     1   50      98      50
2   2     1   60      97      60
3   3     1   55      86      78
4   4     1   30      98      58
5   5     2   25      80      65
6   6     2   50      89      98
7   7     2   80      90      45
8   8     2   55      78      25
9   9     3   20      98      15
10 10     3   50      98      45
11 11     3   65      65      65
12 12     3   45      85      32

 

 

5. 이상치 제거하기 - 존재할 수 없는 값

 

이상치(Outlier)

- 정상 범주에서 크게 벗어난 값

 

1) 이상치가 포함된 데이터 생성

- 1과 2 둘중 하나로 분류되는 sex 변수와 1~5점을 지닐 수 있는 socre 변수로 구성

- 4행의 sex 변수에 이상치 3이 들어 있고, 6행의 score 변수에 이상치 6이 들어가 있음

outlier<-data.frame(sex=c(1,2,1,3,2,1), score=c(5,4,3,4,2,6))
> outlier
  sex score
1   1     5
2   2     4
3   1     3
4   3     4
5   2     2
6   1     6

 

2) 이상치 확인하기 

 

- table()을 이용해 빈도표 생성 

table(outlier$sex)

#1 2 3 
#3 2 1 

table(outlier$score)

#2 3 4 5 6 
#1 1 2 1 1

 

3) 결측 처리하기 

 

- 이상치를 결측치로 변환

- ifelse()를 이용해 이상치일 경우 NA를 부여

 

- sex가 3일 경우 NA를 부여하고, 3일 아닐 경우 원래 가지고 있던 값을 부여 

#sex가 3이면 NA 할당
outlier$sex<-ifelse(outlier$sex==3,NA,outlier$sex)
outlier


 ## sex score
1   1     5
2   2     4
3   1     3
4  NA     4
5   2     2
6   1     6

- score는 1~5점을 지닐 수 있는 값이므로 5보다 크면 NA를 부여 

#score가 5보다 크면 NA 할당
outlier$score<-ifelse(outlier$score>5,NA,outlier$score)
outlier


##  sex score
1   1     5
2   2     4
3   1     3
4  NA     4
5   2     2
6   1    NA

 

- sex, score 변수 모두 이상치를 결측치로 변환했으니 분석할 때 결측치를 제외하면 됨

- filter()를 이용해 결측치를 제외한 후 성별에 따른 score 평균 구하기 

 outlier %>% 
+ filter(!is.na(sex)&!is.na(score)) %>% 
+ group_by(sex) %>% 
+ summarise(mean_score = mean(score))

# A tibble: 2 × 2
    sex mean_score
  <dbl>      <dbl>
1     1          4
2     2          3
>

 

 

6. 이상치 제거하기 - 극단적인 값

 

극단치

 - 논리적으로 존재할 수 있지만 극단적으로 크거나 작은 값

 

1) 상자 그림으로 극단치 기준 정하기 

 

- mpg 데이터의 hwy 변수로 상자그림 만들기 

 boxplot(mpg$hwy)

- 상자 그림은 값을 크기 순으로 나열해 4등분했을 때 위치하는 값인 '사분위수'를 이용해 그려짐

상자 그림 설명
상자 아래 세로 점선 아랫수염 하위 0~25% 내에 해당하는 값
상자 밑면 1사분위수(Q1) 하위 25% 위치 값
상자 내 굵은 선 2사분위수(Q2) 하위 50% 위치 값(중앙값)
상자 윗면 3사분위수(Q3) 하위 75% 위치 값
상자 위 세로 점선 윗수염 하위 75 ~100% 내에 해당하는 값
상자 밖 가로선 극단치 경계 Q1,Q3 밖 1.5 IQR 내 최댓값
상자 밖 점 표식 극단치 Q1,Q3 밖 1.5 IQR을 벗어난 값

- 12~37을 벗어나는 값으 극단치로 분류 

 

 

2) 상자 그림 통계치 

 

boxplot(mpg$hwy)$stats # 상자 그림 통계치 출력

##
     [,1]
[1,]   12 # 극단치 경계
[2,]   18 # 1사분위수
[3,]   24 # 중앙값
[4,]   27 # 3사분위 수 
[5,]   37 # 위쪽 극단치 경계

 

- 출력 결과의 위에서 아래 순으로, 아래쪽 극단치 경계, 1사분위수, 중앙값, 3사분위수, 위쪽 극단치 경계를 의미 

 

 

3) 결측 처리 하기 

 

- 상자 그림을 이용해 정상 범위를 파악했으니 이 범위를 벗어난 값을 결측 처리 

 #12~37 벗어나면 NA 할당
 mpg$hwy<-ifelse(mpg$hwy<12|mpg$hwy>37,NA,mpg$hwy)
 table(is.na(mpg$hwy))

#FALSE  TRUE 
#  231     3

 

- 결측치를 제외하고 간단한 분석

mpg %>% 
+ group_by(drv) %>% 
+ summarise(mean_hwy=mean(hwy,na.rm=T))

# A tibble: 3 × 2
  drv   mean_hwy
  <chr>    <dbl>
1 4         19.2
2 f         27.7
3 r         21

'데이터 > R 프로그래밍' 카테고리의 다른 글

R 프로그래밍 기초 (3)  (0) 2023.10.13
R 프로그래밍 기초(2)  (0) 2023.10.13
R 프로그래밍 기초 (1)  (0) 2023.10.12