본문 바로가기

데이터 분석/R

데이터 분석[R] - 6차시

본 글은 모두를 위한 R 데이터 분석 입문 책을 공부하면서 정리·요약한 내용입니다.

저자 : 오세종

출판 : 한빛아카데미 

 

1. 상관계수

2. - 4 - 인과관계를 알려면 회귀분석을 이용해야 한다.

3. - 4 -

 

결측값(missing value)

더보기

데이터를 수집하고 저장하는 과정에서 저장할 값을 얻지 못하는 경우 발생
→ 고의 또는 실수로 누락
결측값의 처리 방법
1. 결측값 제거 또는 생략
2. 결측값 치환

 

결측값의 특성과 존재 여부 확인

더보기

z <- c(1, 2, 3, NA, 5, NA, 8) # 결측값이 포함된 벡터 z
sum(z) # 정상 계산이 안됨 (NA)
is.na(z) # NA 여부 확인 (FALSE FALSE FALSE TRUE FALSE TRUE FALSE)
sum(is.na(z)) # NA의 개수 확인 (2)
sum(z, na.rm=TRUE) # NA를 제외하고 합계를 계산 (19)

 

결측값의 대체 및 제거

더보기

z1 <- c(1, 2, 3, NA, 5, NA, 8) # 결측값이 포함된 벡터 z1
z2 <- c(5, 8, 1, NA, 3, NA, 7) # 결측값이 포함된 벡터 z2
z1[is.na(z1)] <- 0 # NA를 0으로 치환
z1
z3 <- as.vector(na.omit(z2)) # NA를 생략하고 새로운 벡터 생성
z3

 

결측값이 포함된 데이터프레임 생성

더보기

# NA를 포함하는 test 데이터 생성
x <- iris
x[1, 2] <- NA; x[1, 3] <- NA
x[2, 3] <- NA; x[3, 4] <- NA
head(x)

 

데이터프레임의 열별 결측값 확인

더보기

# for문을 이용한 방법
for(i in 1:ncol(x)){
  this.na <- is.na(x[,i])
  cat(colnames(x)[i], "\t", sum(this.na), "\n")
}

 

# apply를 이용한 방법
col_na <- function(y){
  return (sum(is.na(y)))
}

na_count <- apply(x, 2, FUN=col_na) # 두번째 파라미터 : 1 = 행, 2 = 열을 의미 
na_count

 

데이터프레임의 행별 결측값 확인

더보기

rowSums(is.na(x)) # 행별 NA의 개수

sum(rowSums(is.na(x)) > 0) # NA가 포함된 행의 개수 (3)
sum(is.na(x)) # 데이터셋 전체에서 NA 개수 (4)

 

결측값을 제외하고 새로운 데이터 셋 만들기

더보기

head(x)

x[!complete.cases(x),] # NA가 포함된 행들 출력

y <- x[complete.cases(x),] # NA가 포함된 행들 제거
head(y)

 

특이값

더보기

특이값(outlier)은 정상적 데이터의 분포 범위 밖에 위치하는 값들을 말하며, ‘이상치’라고도 부름

데이터 분석에서는 특이값을 포함한 채 평균 등을 계산하면 전체 데이터의 양상을 파악하는 데 왜곡을 가져올 수 있으므로 분석할 때 특이값을 제외하는 경우가 많음

 

특이값이 포함되어 있는지 여부 확인

더보기

➀ 논리적으로 있을 수 없는 값이 있는지 찾아봄

➁ 상식을 벗어난 값이 있는지 찾아봄

➂ 상자그림(boxplot)을 통해 찾아봄

 

상자그림을 통한 특이값 확인

더보기

특이값인지 판별 :  Q1-1.5*IQR보다 작거나 Q3+1.5*IQR보다 큰 값

IQR (Internal quantile Range) : Q1 ~ Q3 사이의 범위 (Q3 - Q1)

 

str(state.x77) # array 형태 
st <- data.frame(state.x77) # 데이터프레임으로 변환
boxplot(st$Income) # 상자그림 출력

boxplot.stats(st$Income)$out # 특이값 확인 (6315)

 

특이값을 포함한 행 제거

더보기

특이값을 NA로 바꾸고 NA를 포함한 행을 제거하는 방식으로 진행

%in% : 어떤 벡터에 비교하고자 하는 값이 포함되어 있는지를 알고 싶을 때 사용

 

out.val <- boxplot.stats(st$Income)$out # 특이값 추출
# 특이값을 NA로 대체
st$Income[st$Income%in% out.val] <- NA # st$Income에서 out.val(6315) 값 NA로 치환
head(st)

newdata <- st[complete.cases(st),] # NA가 포함된 행 제거
head(newdata)

 

특이값 판별 방법

더보기

ESD(Extreme Studentized Deviation) 사용

ESD : 평균으로부터 k 표준편차 떨어진 값 (k는 일반적으로 3을 적용)

 

정상적인 값 : 기하평균-2.5*표준편차 < data < 기하평균+2.5*표준편차

기하평균 : 값을 모두 곱한 후 n제곱근한 값

 

사분위수 이용하여 제거

Q1-1.5*IQR < data < Q3+1.5*IQR를 벗어나는 데이터

IQR : Q1 ~ Q3 사이의 범위 (Q3 - Q1)

 

연습문제

더보기

state.x77 데이터셋을 st에 저장한 후 다음 문제를 해결하시오.
st <- data.frame(state.x77)
(1) st의 각 변수(열)들에 대해 특이값이 존재하는지 상자그림을 그려 확인하시오.
par(mfrow=c(2,4))
for(i in 1:ncol(st)){
  boxplot(st[,i], main=colnames(st)[i])
}

par(mfrow=c(1,1))
(2) 특이값이 존재하는 경우 이상치를 NA로 대체하여 저장하시오.
pop.outval <- boxplot.stats(st$Population)$out # 특이값 추출
st$Population[st$Population %in% pop.outval] <- NA # 특이값을 NA로 대체
boxplot.stats(st$Population)$out # 특이값을 NA로 대체 확인

income.outval <- boxplot.stats(st$Income)$out # 특이값 추출
st$Income[st$Income %in% income.outval] <- NA # 특이값을 NA로 대체
boxplot.stats(st$Income)$out # 특이값을 NA로 대체 확인

Area.outval <- boxplot.stats(st$Area)$out # 특이값 추출
st$Area[st$Area %in% Area.outval] <- NA # 특이값을 NA로 대체
boxplot.stats(st$Area)$out # 특이값을 NA로 대체 확인
(3) st에서 NA가 존재하는 행들을 제거하여 st2에 저장하시오.
st2 <- st[complete.cases(st),] # NA가 포함된 행 제거
# 특이값이 제거된 상자그림 확인
par(mfrow=c(2,4))
for(i in 1:ncol(st)){
  boxplot(st[,i], main=colnames(st)[i])
}

par(mfrow=c(1,1))

 

벡터의 정렬

더보기

v1 <- c(1,7,6,8,4,2,3)
order(v1) # 번호표를 준다. 원래 순서를 그대로 유지하면서 정렬된 결과를 보여준다. (1 6 7 5 3 2 4)

v1 <- sort(v1) # 오름차순
v1 # (1 2 3 4 6 7 8)
v2 <- sort(v1, decreasing=T) # 내림차순
v2 # (8 7 6 4 3 2 1)

 

매트릭스와 데이터프레임의 정렬

더보기

head(iris)
order(iris$Sepal.Length)
iris[order(iris$Sepal.Length),] # 오름차순으로 정렬(디폴트 값)
iris[order(iris$Sepal.Length, decreasing=T),] # 내림차순으로 정렬
iris.new <- iris[order(iris$Sepal.Length),] # 정렬된 데이터를 저장
head(iris.new)
iris[order(iris$Species, -iris$Petal.Length, decreasing=T),] # 정렬 기준이 2개( 데이터베이스에서 order by 개념과 같다.), -를 붙이면 정렬 반대 적용(디폴트가 내림차순이므로 -를 붙이면 오름차순이 됨), 문자열에는 -를 붙일 수 없음

 

데이터 분리

더보기

하나의 데이터셋을 열의 값을 기준으로 여러 개의 데이터셋으로 분리할 때는 split() 함수를 이용
sp <- split(iris, iris$Species) # 품종별로 데이터 분리
sp # 분리 결과 확인
summary(sp) # 분리 결과 요약

# 위 코드는 하나의 리스트안에 각각의 데이터프레임 3개가 들어가 있다는 것을 의미한다.
sp$setosa # setosa 품종의 데이터 확인

 

데이터 선택

더보기

데이터셋으로부터 조건에 맞는 행들을 추출할 때는 subset() 함수를 이용

select 매개변수 : 추출할 열을 지정하는 역할

subset(iris, Species == "setosa") # Species가 setosa인 것만 출력
subset(iris, Sepal.Length > 7.5) # Sepal.Length가 7.5 초과인 것만 출력
subset(iris, Sepal.Length >5.1 & Sepal.Width > 3.9) # Sepal.Length가 5.1이상이고 Sepal.Width가 3.9 초과인 것만 출력 
subset(iris, Sepal.Length > 7.6, select = c(Petal.Length, Petal.Width)) # Sepal.Length가 7.6 초과인 것들 중 Petal.Length, Petal.Width 열만 출력

 

연습문제

더보기

mtcars 데이터셋으로 다음 문제를 해결하시오.
(1) mtcars 데이터셋을 gear(기어)의 개수에 따라 그룹을 나누어 mt.gear에 저장하시오.(단, split() 함수를 사용하시오.)
mt.gear <- split(mtcars, mtcars$gear)
summary(mt.gear.n)
(2) mt.gear에서 gear(기어)의 개수가 4인 그룹의 데이터를 출력하시오. (힌트 : mt.gear$'4')
mt.gear$'4'
(3) mt.gear에서 gear(기어)의 개수가 3인 그룹과 5인 그룹의 데이터를 합쳐서 mt.gear.35에 저장하고 내용을 출력하시오. (힌트 : rbind)
mt.gear.35 <- rbind(mt.gear$'3', mt.gear$'5')
mt.gear$'3'
mt.gear.35
(4) mtcars 데이터셋에서 wt(중량)가 1.5~3.0 사이인 행들을 추출하여 출력하시오.
subset(mtcars, wt >= 1.5 & wt <= 3.0)

20210702.R
0.01MB

반응형

'데이터 분석 > R' 카테고리의 다른 글

데이터 분석[R] - 8차시  (0) 2021.07.06
데이터 분석[R] - 7차시  (0) 2021.07.05
데이터 분석[R] - 5차시  (0) 2021.07.01
데이터분석[R] - 4차시  (0) 2021.06.30
데이터 분석[R] - 3차시  (0) 2021.06.29