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 |