본 글은 모두를 위한 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)
'데이터 분석 > 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 |