무작정 따라하는 공부법 ! 무따공입니다~
벌써 다섯번째 포스팅이네요 ㅎㅎ
패키지 함수를 몇가지 다루는데, 잘 따라오세요!
----------------------------------------------------------------
1. 데이터 전처리기
- 분석에 적합한 데이터로 가공하는 작업을 데이터 전처리(Data Preprocessing)라고 한다.
- dplyr패키지는 데이터 전처리 작업에 가장 많이 사용된다.
(1) 조건에 맞는 데이터 추출
- filter(조건식)를 이용하여 원하는 데이터를 추출할 수 있다.
library(dplyr)
exam <- read.csv("csv_exam.csv")
exam
# exam에서 class가 1인 경우만 추출하여 출력
exam %>% filter(class == 1)
# 2반인 경우만 추출
exam %>% filter(class == 2)
# 1반이 아닌 경우
exam %>% filter(class != 1)
# 3반이 아닌 경우
exam %>% filter(class != 3)
## -------------------------------------------------------------------- ##
# 수학 점수가 50점을 초과한 경우
exam %>% filter(math > 50)
# 수학 점수가 50점 미만인 경우
exam %>% filter(math < 50)
# 영어 점수가 80점 이상인 경우
exam %>% filter(english >= 80)
# 영어 점수가 80점 이하인 경우
exam %>% filter(english <= 80)
## -------------------------------------------------------------------- ##
# 1반이면서 수학 점수가 50점 이상인 경우
exam %>% filter(class == 1 & math >= 50)
# 2반이면서 영어 점수가 80점 이상인 경우
exam %>% filter(class == 2 & english >= 80)
## -------------------------------------------------------------------- ##
# 수학 점수가 90점 이상이거나 영어 점수가 90점 이상인 경우
exam %>% filter(math >= 90 | english >= 90)
# 영어 점수가 90점 미만이거나 과학점수가 50점 미만인 경우
exam %>% filter(english < 90 | science < 50)
## -------------------------------------------------------------------- ##
# 1, 3, 5 반에 해당되면 추출
exam %>% filter(class == 1 | class == 3 | class == 5)
exam %>% filter(class %in% c(1,3,5))
## -------------------------------------------------------------------- ##
class1 <- exam %>% filter(class == 1) # class가 1인 행 추출, class1에 할당
class2 <- exam %>% filter(class == 2) # class가 2인 행 추출, class2에 할당
mean(class1$math) # 1반 수학 점수 평균 구하기
mean(class2$math) # 2반 수학 점수 평균 구하기
(3) 필요한 변수만 추출
- select()는 데이터에 들어 있는 수 많은 변수 중 일부 변수만 추출해 활용하고자 할 때 사용한다.
exam %>% select(math) # math 추출
exam %>% select(english) # english 추출
exam %>% select(class, math, english) # class, math, english 변수 추출
exam %>% select(-math) # math 제외
exam %>% select(-math, -english) # math, english 제외
- filter()와 select() 조합
# class가 1인 행만 추출한 다음 english 추출
exam %>% filter(class == 1) %>% select(english)
exam %>%
filter(class == 1) %>% # class가 1인 행 추출
select(english) # english 추출
exam %>%
select(id, math) %>% # id, math 추출
head # 앞부분 6행까지 추출
exam %>%
select(id, math) %>% # id, math 추출
head(10) # 앞부분 10행까지 추출
(4) 순서대로 정렬
- arrange()를 이용하여 데이터를 원하는 순서로 정렬할 수 있다.
- default가 오름차순이며 desc()를 사용하여 내림차순을 지정할 수 있다.
exam %>% arrange(math) # math 오름차순 정렬
exam %>% arrange(desc(math)) # math 내림차순 정렬
exam %>% arrange(class, math) # class 및 math 오름차순 정렬
(5) 파생변수 추가
- mutate()를 사용하여 기존 데이터에 파생변수를 추가할 수 있다.
exam %>%
mutate(total = math + english + science) %>% # 총합 변수 추가
head # 일부 추출
exam %>%
mutate(total = math + english + science, # 총합 변수 추가
mean = (math + english + science)/3) %>% # 총평균 변수 추가
head # 일부 추출
exam %>%
mutate(test = ifelse(science >= 60, "pass", "fail")) %>%
head
exam %>%
mutate(total = math + english + science) %>% # 총합 변수 추가
arrange(total) %>% # 총합 변수 기준 정렬
head # 일부 추출
(6) 집단별로 요약
- 집단별 평균이나 집단별 빈도처럼 각 집단을 요약한 값을 group_by()와
summarise()를 사용한다.
exam %>% summarise(mean_math = mean(math)) # math 평균 산출
exam %>%
group_by(class) %>% # class별로 분리
summarise(mean_math = mean(math)) # math 평균 산출
- 여러 요약 통계량을 한번에 산출할 수 있다.
exam %>%
group_by(class) %>% # class별로 분리
summarise(mean_math = mean(math), # math 평균
sum_math = sum(math), # math 합계
median_math = median(math), # math 중앙값
n = n()) # 학생 수
※ summarise()에 자주사용 하는 요약 통계랑 함수
- group_by()에 여러 변수를 지정하면 집단을 나눈 후 다시 하위 집단으로 나눌 수 있다.
- mpg(자동차 정보)데이터를 이용하여 하위집단별 평균을 구한다., 회사별로 집단을 나눈 후
다시 구동 방식별로 나눠 도시 연비 평균을 구한다.
mpg %>%
group_by(manufacturer, drv) %>% # 회사별, 구동방식별 분리
summarise(mean_cty = mean(cty)) %>% # cty 평균 산출
head(10) # 일부 출력
manufacturer drv mean_cty
<chr> <chr> <dbl>
1 audi 4 16.81818
2 audi f 18.85714
3 chevrolet 4 12.50000
4 chevrolet f 18.80000
5 chevrolet r 14.10000
6 dodge 4 12.00000
7 dodge f 15.81818
8 ford 4 13.30769
9 ford r 14.75000
10 honda f 24.44444
drv 변수: 4->사륜구동, f->전륜구동, r ->후륜구동
- dplyr패키지의 함수들을 하나의 구문으로 조합하여 아래의 분석 문제를 해결하자.
회사별 'suv' 자동차의 도시 및 고속도로 통합 연비 평균을 구해 내림차순으로 정렬하고,
1~5위까지 출력하기
※ 작성 절차에 따른 기능별 함수
1. 회사별로 분리 -> group_by()
2. SUV추출 -> filter()
3. 통합 연비 변수 생성 -> mutate()
4. 통합 연비 평균 산출 -> summarise()
5. 내림차순 정렬 -> arrange()
6. 1~5까지 출력 -> head()
mpg %>%
group_by(manufacturer) %>% # 회사별로 분리
filter(class == "suv") %>% # suv 추출
mutate(tot = (cty+hwy)/2) %>% # 통합 연비 변수 생성
summarise(mean_tot = mean(tot)) %>% # 통합 연비 평균 산출
arrange(desc(mean_tot)) %>% # 내림차순 정렬
head(5) # 1~5위까지 출력
(7) 데이터 합치기
1) 가로로 합치기
- 두개의 데이터 프레임을 만들고 dplyr패키지의 left_join()을 이용하여 데이터를
가로로 합친다.
- 기준변수명은 by에 지정한다.
# 중간고사 데이터 생성
test1 <- data.frame(id = c(1, 2, 3, 4, 5),
midterm = c(60, 80, 70, 90, 85))
# 기말고사 데이터 생성
test2 <- data.frame(id = c(1, 2, 3, 4, 5),
final = c(70, 83, 65, 95, 80))
test1 # test1 출력
test2 # test2 출력
total <- left_join(test1, test2, by = "id") # id 기준으로 합쳐서 total에 할당
total # total 출력
- 각반학생 명단에 담임교사 명단 추가하기
name <- data.frame(class = c(1, 2, 3, 4, 5),
teacher = c("kim", "lee", "park", "choi", "jung"))
name
exam_new <- left_join(exam, name, by = "class")
exam_new
2) 세로로 합치기
- bind_rows()함수를 이용하여 데이터를 세로로 합친다.
- 우선 다섯명이 시험을 보고 나중에 다섯명이 따로 시험본결과를
세로로 합친다.
# 학생 1~5번 시험 데이터 생성
group_a <- data.frame(id = c(1, 2, 3, 4, 5),
test = c(60, 80, 70, 90, 85))
# 학생 6~10번 시험 데이터 생성
group_b <- data.frame(id = c(6, 7, 8, 9, 10),
test = c(70, 83, 65, 95, 80))
group_a # group_a 출력
group_b # group_b 출력
group_all <- bind_rows(group_a, group_b) # 데이터 합쳐서 group_all에 할당
group_all # group_all 출력
2. 데이터 정제
(1) 결측치 정제하기
- 결측치(Missing Value)는 누락된 값, 비어 있는 값의미
- 결측치로 이인해 함수가 적용이 안되거나 분석결과가 왜곡되는 문제가 발생할 수 있다.
- 결측치를 없애는 정제과정이 필요하다.
- R에서 결측치는 NA로 표시된다. 결측지를 확인하기 위해서는 is.na()로 확인한다.
- 결측치를 제거하기위해 is.na()를 filter()적용하면 결측치 행을 제거할 수 있다.
#결측치가 포함된 데이터 생성
df <- data.frame(gender = c("M", "F", NA, "M", "F"),
score = c(5, 4, 3, 4, NA))
df
is.na(df) # 결측치 확인
table(is.na(df)) # 결측치 빈도 출력
table(is.na(df$gender)) # gender 결측치 빈도 출력
table(is.na(df$score)) # score 결측치 빈도 출력
#결측치가 포함된 데이터는 함수 적용시 연산되지 못하고 NA값 출력한다.
mean(df$score) # 평균 산출
sum(df$score) # 합계 산출
#결측치 제거library(dplyr) # dplyr 패키지 로드
df %>% filter(is.na(score)) # score가 NA인 데이터만 출력
df %>% filter(!is.na(score)) # score 결측치 제거
#결측치가 제거되면 함수가 적용된다.
df_nomiss <- df %>% filter(!is.na(score)) # score 결측치 제거
mean(df_nomiss$score) # score 평균 산출
sum(df_nomiss$score) # score 합계 산출
#성별및 점수의 결측치 제거
df_nomiss <- df %>% filter(!is.na(score) & !is.na(gender)) # score, gender 결측치 제거
df_nomiss # 출력
#na.omit()를 이용하면 결측치가 있는행을 한번에 제거할 수 있다.
df_nomiss2 <- na.omit(df) # 모든 변수에 결측치 없는 데이터 추출
df_nomiss2 # 출력
- 함수 자체에 결측치 제외 기능(na.rm)이 있는경우는 그기능을 사용하여 함수를 적용한다.
결측치 제외 기능이 없을시에는 fillter()로 결측지를 제거한다.
dfmean(df$score, na.rm = T) # 결측치 제외하고 평균 산출
sum(df$score, na.rm = T) # 결측치 제외하고 합계 산출
exam <- read.csv("csv_exam.csv") # 데이터 불러오기
exam[c(3, 8, 15), "math"] <- NA # 3, 8, 15행의 math에 NA 할당
exam
exam %>% summarise(mean_math = mean(math)) # math 평균 산출
# math 결측치 제외하고 평균 산출
exam %>% summarise(mean_math = mean(math, na.rm = T))
exam %>% summarise(mean_math = mean(math, na.rm = T), # 평균 산출
sum_math = sum(math, na.rm = T), # 합계 산출
median_math = median(math, na.rm = T)) # 중앙값 산출
- 결측치를 제거 하는 대신 다른 값으로 대체할 수 있다.mean(exam$math, na.rm = T) # 결측치 제외하고 math 평균 산출
exam$math <- ifelse(is.na(exam$math), 55, exam$math) # math가 NA면 55로 대체
table(is.na(exam$math)) # 결측치 빈도표 생성
exam # 출력
mean(exam$math) # math 평균 산출
(2) 이상치 정제하기
- 정상범주에서 크게 벗어난 값을 이상치(Outlier)라고 한다.
- 오류는 아니지만 굉장히 드물게 극단적인 값이 있을 수도 있다.
- 분석적 이런 이상치를 제거 해야 한다.
- 이상치를 결측치로 변화하여 결측치를 제거한다.
성별은 1과 2 , 점수는 1~5
# 이상치값을 성별에 3, 점수에 6을 넣어서 생성한다.
outlier <- data.frame(gender = c(1, 2, 1, 3, 2, 1),
score = c(5, 4, 3, 4, 2, 6))
outlier
table(outlier$gender)
table(outlier$score)
# gender가 3이면 NA 할당
outlier$gender <- ifelse(outlier$gender == 3, NA, outlier$gender)
outlier
# score가 5보다 크면 NA 할당
outlier$score <- ifelse(outlier$score > 5, NA, outlier$score)
outlier
outlier %>%
filter(!is.na(gender) & !is.na(score)) %>%
group_by(gender) %>%
summarise(mean_score = mean(score))
- 극단적으로 크거나 작은 값을 극단치라 하는데 몸무게가 200kg 이상의 값은
존재가능성은 있지만 굉장히 드문경우이다. 데이터에 극단치가 있으면 분석결과가
왜곡 될 수 있으므로 제거 해야 한다.
- 아래의 상자 그림은 데이터의 분포를 직사각형의 상자 모양으로 표현한다.
데이터 분포를 한눈에 볼수 있는데 그림에서 극단치를 확인할 수 있다.
※상자그림의 값과 설명
* 1.5 IQR 값은 사분위 범위(Q1~Q3간 거리)의 1.5배를 위미한다.
boxplot(mpg$hwy) #위 상자그림과 같다.
- 위 상자 그림의 윗수염과 아랫수염 위와 아래의 가로선의 값을 보면 12~37을 벗어났다.
# 상자 그림 통계치 출력
boxplot(mpg$hwy)$stats > boxplot(mpg$hwy)$stats
[,1]
[1,] 12
[2,] 18
[3,] 24
[4,] 27
[5,] 37
attr(,"class")
1
"integer"
> # 12~37 벗어나면 NA 할당
mpg$hwy <- ifelse(mpg$hwy < 12 | mpg$hwy > 37, NA, mpg$hwy)
# 결측치 확인
table(is.na(mpg$hwy))
#결측치 제외하고 drv그룹별 평균값출력
mpg %>%
group_by(drv) %>%
summarise(mean_hwy = mean(hwy, na.rm = T))
댓글