16. dplyr 패키지 실습
in Study on R Programming
Overview
R의 dplyr 패키지 실습을 해본다.
예제 파일1 : 2013년_프로야구선수_성적.csv
예제 파일2 : jumsu.csv
예제 파일3 : progbook.csv
예제 파일4 : R정형데이터처리하기.xlsx
dplyr 패키지 실습 1
# dplyr package : c++ 언어로 개발되어 처리 속도 개선
# install.packages('dplyr')
library(dplyr)
data <- read.csv('2013년_프로야구선수_성적.csv')
data
str(data)
# filter 함수를 통해 120 경기 이상 뛴 선수 조회
data2 <- filter(data, 경기 >= 120)
data2
data[c('경기', '득점')]
# 경기 >= 120, 득점 >= 80
data3 <- filter(data, 경기 >= 120 & 득점 >= 80)
data3
# 포지션이 '1루수', '3루수'
data4 <- filter(data, 포지션 == '1루수' | 포지션 == '3루수')
data4
# %in% : in 연산자
data4 <- filter(data, 포지션 %in% c('1루수', '3루수'))
data4
# 선수명, 포지션, 팀
data5 <- select(data, c(선수명, 포지션, 팀))
data5
colnames(data)
data6 <- select(data, 순위:타수)
data6
# 포지션이 1루수 또는 3루수인 선수들의 선수명, 포지션, 득점
data7 <- select(data4, c(선수명, 포지션, 팀))
data7
# %>% : 여러개의 문장을 조합하여 사용하고자 할때
# select나 filter안에 있는 data 변수를 빼야한다.
result <- data %>% filter(포지션 %in% c('1루수', '3루수')) %>% select(c(선수명, 포지션, 팀))
result
# 홈런, 타점을 제외하고 select
data8 <- select(data, -c(홈런, 타점))
data8
# 선수이름, 팀, 경기, 타수 조회
# 타수가 400 이상
data9 <- filter(data[c('선수명', '팀', '경기', '타수')], 타수 >= 400)
data9
data10 <- data %>% arrange(홈런)
data10
data11 <- data %>% arrange(desc(홈런))
data11
# caution : select와 arrange의 순서 주의.
# 정렬 후 select해야함
# select를 먼저 하면 뒤에서 select된 컬럼 이외의 컬럼을 사용할 수 없음
data12 <- data %>% arrange(desc(홈런)) %>% select(c('선수명', '팀', '경기', '타수')) %>% filter(타수 >= 400)
data12
# mutate 함수
# 컬럼의 연산을 통해 컬럼 생성
data13 <- data %>% select(선수명, 팀, 경기, 타수) %>% mutate(결과 = 경기 * 타수)
data13
data
# 선수명, 팀, 경기, 타수, 루타의 합
# 루타의 합 = 1루타 + 2루타 + 3루타
# 루타의 합에 대해 오름차수 정렬
data14 <- data %>% mutate(루타의합 = (안타 + X2루타 + X3루타)) %>% arrange(루타의합) %>% select(선수명, 팀, 경기, 타수, 루타의합)
data14
# 팀별 평균 경기 수
# group_by로 팀별로 그룹핑을 한 뒤 경기의 평균값을(mean) 정렬(arrange) 별도 컬럼으로 생성(summarise)
data[c('팀', '경기')]
data16 <- data %>% group_by(팀) %>% summarise(arrange=mean(경기, na.rm = T))
data16
# 경기와 타수의 각각의 평균 구하기
data17 <- data %>% group_by(팀) %>% summarise_each(list(mean), 경기, 타수)
data17
# n()함수 : 개수 확인(도수), 직관적이지 못하니 확인
data18 <- data %>% group_by(팀) %>% summarise_each(funs(mean, n()), 경기, 타수)
data18
dplyr 패키지 실습 2
library(dplyr)
students <- read.csv("jumsu.csv")
head(students)
#
# students에서 ban가 1인 경우만 출력하세요.
#
ex1 <- filter(students, ban == 1)
ex1
# students에서 3반이 아닌 경우만 출력하세요.
#
ex2 <- filter(students, ban != 3)
ex2
# 국어 점수가 50점을 초과한 경우만 출력하세요.
#
ex3 <- filter(students, kor > 50)
ex3
# 영어 점수가 80점 이하인 경우만 출력하세요.
#
ex4 <- filter(students, eng <= 80)
ex4
# 1반이면서 국어 점수가 50점 이상인 경우만 출력하세요.
#
ex5 <- filter(students, ban == 1 & kor >= 50)
ex5
# 국어 점수가 90점 이상이거나 영어 점수가 90점 이상인 경우만 출력하세요.
#
ex6 <- filter(students, eng >= 90 & kor >= 90)
ex6
# 영어 점수가 90점 미만이거나 수학 점수가 50점 미만인 경우
#
ex7 <- filter(students, eng < 90 & math < 50)
ex7
# # %in% 기호를 사용하면 코드를 좀 더 간결하게 작성할 수 있다.
# # %in% 기호와 c() 함수를 이용해 조건 목록을 입력하면 된다.
#
# # 1, 3, 5반 학생들 정보를 출력하시오.
#
ex8 <- filter(students, ban %in% c('1','3', '5'))
ex8
# 1반 학생들 정보를 변수 ban1에 저장하시오.
#
ban1 <- filter(students, ban == 1)
ban1
# 2반 학생들 정보를 변수 ban2에 저장하시오.
#
ban2 <- filter(students, ban == 2)
ban2
# 변수 ban1의 국어 점수 평균을 구하시오.
#
ex9 <- mean(ban1$kor)
ex9
# 변수 ban2의 영어 점수 평균을 구하시오.
#
ex10 <- mean(ban2$eng)
ex10
# kor 컬럼만 추출하시오.
#
ex11 <- select(students, kor)
ex11
# ban, kor, eng 컬럼을 추출하시오.
#
ex12 <- select(students, eng)
ex12
# kor, eng 컬럼을 제외하고 나머지 컬럼만 추출하시오.
#
ex13 <- select(students, -c('kor', 'eng'))
ex13
# 1반 학생들의 eng 컬럼만 추출하시오.
#
ex14 <- select(ban1, eng)
ex14
# id, kor 추출하되, 앞부분 10행까지만 추출하시오.
# 힌트 : head() 함수도 사용할 수 있다.
#
ex15 <- head(select(students, c('id', 'kor')), 10)
ex15
# 국어 점수를 이용하여 오름차순으로 정렬하시오.
#
ex16 <- students %>% arrange(kor)
ex16
# 영어 점수를 이용하여 내림차순으로 정렬하시오.
#
ex17 <- students %>% arrange(desc(kor))
ex17
# 반(ban)별 오름차순 정렬 후, 국어(kor) 점수별로 내림차순 정렬하시오.
#
ex18 <- students %>% arrange(ban) %>% arrange(desc(kor))
ex18
# 총점 컬럼을 만들어 보세요.
# 총점(total) = kor + eng + math
#
ex19 <- students %>% mutate(total = kor + eng + math)
ex19
# 평균 컬럼을 만들어 보세요.
# 평균(average) = total / 3
#
ex20 <- ex19 %>% mutate(average = round((total / 3), 2))
ex20
# result 컬럼을 만들어 보세요.
# result 컬럼은 수학 점수가 60이상이면 pass, 아니면 fail이라는 값을 저장해야 한다.
# 힌트 : ifelse 함수를 사용하면 된다.
#
ex21 <- ex20 %>% mutate(result = (ifelse(students$math >= 60, 'pass', 'fail')))
ex21
# 총합 컬럼 기준으로 오름차순 정렬하시오
#
ex22 <- ex21 %>% arrange(total)
ex22
# 국어 점수의 평균을 구한 후 mean_kor이라는 새로운 변수에 값을 할당해 보세요.
#
mean_kor = round(mean(students$kor), 2)
mean_kor
# 반별로 국어 점수의 평균과 영어 점수의 총합 및 학생 수를 구해 보세요(힌트 : n() 함수)
ex23 <- ex21 %>% group_by(ban) %>% summarise(국어점수평균 = mean(kor), 영어점수총합 = sum(eng), 학생수 = n())
ex23
dplyr 패키지 실습 3
# dplyr와 plyr의 순서 문제로 인해 detach가 선행
detach("package:plyr", unload = TRUE)
detach("package:dplyr", unload = TRUE)
# plyr가 dplyr보다 빠르게 로드해야함
library(plyr)
library(dplyr)
prog <- read.csv('progbook.csv', header = T)
prog
# between
# filter(prog, between(column, 하한값, 상한값))
# qty가 5이상 7이하 데이터를 조회
filter(prog, between(qty, 5, 7))
# top_n : 상위 n개만 가져오기
# top_n(prog, 4, qty)
# case_when
# mutate(result = case_when(조건1 ~ 내용1, 조건2 ~ 내용2, ..., T ~ 기타 등등))
# price가 12000이상은 high, 6000이상은 middle, 나머지는 low로 표현
ex0 <- prog %>% mutate(result = case_when(price >= 12000 ~ 'high', price >= 6000 ~ 'middle', T ~ 'low' ))
ex0
prog$name
# 프로그램별 판매 수량의 합과 총 판매 금액을 구하세요.
ex1 <- prog %>% group_by(name) %>% summarise(qsum = sum(qty, na.rm = T), psum = sum(qty*price, na.rm = T))
ex1
# 프로그램별 최대 판매 수량과 최소 판매 금액을 구하세요.
ex2 <- prog %>% group_by(name) %>% summarise(mxq = max(qty, na.rm = T), mip = min(qty*price, na.rm = T))
ex2
# 년도별, 프로그램 최대 판매 수량과 최소 금액을 구하세요.
ex3 <- prog %>% group_by(year) %>% summarise(mxq = max(qty, na.rm = T), mip = min(qty*price, na.rm = T))
ex3
# 프로그램 판매 수량의 합과 ////////////////////////////비율을 구하세요.
# 비율 : 판매수량/전체판매수량
ex4 <- ddply(prog, 'name', transform, sumqty = sum(qty), percent = qty/sum(qty) * 100)
ex4
dplyr 패키지 실습 4
member <- read.csv('member.csv', header = T)
member
board <- read.csv('board.csv', header = T)
board
# col name 확인
colnames(member)
colnames(board)
help(merge)
# merge 함수의 사용, 기본 옵션은 inner join
result <- merge(member, board, by = '아이디')
result
# merge 함수의 all 옵션, ouuer join
result <- merge(member, board, by = '아이디', all = T)
result
library(plyr)
# join 함수의 기본값은 left outter join
result <- join(member, board, by = '아이디')
result
# full : 기본값과 같음, inner : inner join
result <- join(member, board, by = '아이디', type = full)
result
result <- join(member, board, by = '아이디', type = inner)
result
# groupping을 할 수 있는 tapply 함수
tapply(member$급여, member$성별, mean)
# 성별로 적립 포인트의 합
tapply(member$적립포인트, member$성별, sum)
help(ddply)
# ddply(대상, 그룹핑할 컬럼, summarise, 데이터1, 데이터2)
# summarise : 그룹핑한 컬럼만 따로 빼서 출력
result <- ddply(member, .(성별), summarise, meanData = mean(급여), sumData = sum(급여))
result
# ddply(대상, 그룹핑할 컬럼, transform, 데이터1, 데이터2)
# transform : 기존 테이블에 그룹핑한 컬럼 추가
# transform의 예제는 대부분 percent 구하는 것
# percent : 해당 그룹 내에서의 비율
result <- ddply(member, .(성별), transform, meandata = mean(급여), sumData = sum(급여), percent = 급여/sum(급여))
result
dplyr 패키지 실습 5
detach("package:plyr", unload = TRUE)
detach("package:dplyr", unload = TRUE)
# plyr가 dplyr보다 빠르게 로드해야함
library(plyr)
library(dplyr, warn.conflicts = FALSE)
library(rJava)
library(xlsx)
# R정형데이터처리하기.xlsx 파일을 읽어 들이세요.
# 가전제품1~가전제품3 시트를 읽어 와서 하나의 데이터프레임(이름 : myframe)에 병합하시오.
# 단, 분기 구분이 있어야 하므로 quarter(분기 컬럼 이름)을 하나 추가하도록 한다.
myencoding = 'UTF-8'
filename = 'R정형데이터처리하기.xlsx'
sheets <- c(3:5)
myframe <- data.frame()
for( onesheet in sheets ){
print(onesheet)
dframe <- read.xlsx(file=filename, sheetIndex = onesheet, encoding=myencoding)
dframe$quarter <- paste((onesheet-2), "사분기", sep='')
myframe <- rbind(myframe, dframe)
}
myframe
# myframe에서 quarter가 1사분기인 경우만 출력하세요.
#
ex1 <- filter(myframe, quarter %in% '1사분기')
ex1
# myframe에서 3사분기가 아닌 경우만 출력하세요.
#
ex2 <- filter(myframe, quarter != '3사분기')
ex2
# 전체에서 불량품 수 40을 초과한 경우만 출력하세요.
#
ex3 <- filter(myframe, 불량품 > 40)
ex3
# 1일생산량이 100~150인 경우만 출력하세요.(between 사용)
#
ex4 <- filter(myframe, between(X1일생산량, 100, 150))
ex4
# 1사분기이면서 1일생산량이 200이하인 경우만 출력하세요.
#
ex5 <- filter(myframe, quarter %in% '1사분기' & X1일생산량 <= 200)
ex5
# 총생산량이 10000 이상이거나 불량품이 35이하인 경우만 출력하세요.
#
ex6 <- filter(myframe, 총생산량 >= 10000 | 불량품 <= 35)
ex6
# # %in% 기호를 사용하면 코드를 좀 더 간결하게 작성할 수 있다.
# # %in% 기호와 c() 함수를 이용해 조건 목록을 입력하면 된다.
#
# # 1사분기, 3사분기 데이터를 출력하시오.
#
ex7 <- filter(myframe, quarter %in% c('1사분기', '3사분기'))
ex7
# 1사분기 정보를 변수 quarter1에 저장하시오.
#
quarter1 <- filter(myframe, quarter %in% c('1사분기'))
quarter1
# 2사분기 정보를 변수 quarter2에 저장하시오.
#
quarter2 <- filter(myframe, quarter %in% c('2사분기'))
quarter2
# 변수 quarter1의 1일생산량 평균을 구하시오.(mean 함수)
#
ex8 <- mean(quarter1$X1일생산량)
ex8
# 변수 quarter2의 총생산량의 총합을 구하시오.(sum 함수)
#
ex9 <- sum(quarter1$총생산량)
ex9
# 1사분기의 총생산량 컬럼만 추출하시오.
#
ex10 <- quarter1 %>% select(총생산량)
ex10
# 전체에서 제품명과 1일생산량의 앞부분 10행까지만 추출하시오.
# 힌트 : head() 함수도 사용할 수 있다.
#
ex11_1 <- myframe %>% select(제품명, X1일생산량)
ex11 <- head(ex11_1, 10)
ex11
# 출고량를 기준으로 오름차순으로 정렬하시오.
#
ex12 <- myframe %>% arrange(출고량)
ex12
# 총생산량을 기준으로 내림차순으로 정렬하시오.
#
ex12 <- myframe %>% arrange(desc(총생산량))
ex12
# 분기(quarter)별 오름차순 정렬 후, 불량품으로 내림차순 정렬하시오.
#
ex13 <- myframe %>% arrange(quarter) %>% arrange(desc(불량품))
ex13
# 불량률 컬럼을 만들어 보되, 소수점 3자리까지 표현하시오.
# 불량률 = 불량품 / 총생산량
ex14 <- myframe %>% mutate(불량률 = (round(불량품 / 총생산량, 5) * 100))
ex14
# result 컬럼을 만들어 보세요.
# result 컬럼은 불량률 컬럼이 얼마이상이면 'bad', 아니면 'good'이라는 값을 저장해야 한다.
# 힌트 : ifelse 함수를 사용하면 된다.
#
ex15 <- ex14 %>% mutate(result = ifelse(불량률 < 0.4, 'good', 'bad'))
ex15
# 불량률 컬럼 기준으로 오름차순 정렬하시오.
#
ex16 <- ex15 %>% arrange(불량률)
ex16
# 분기별로 총생산량의 평균과 불량품의 총합 및 도수를 구해 보세요(힌트 : n() 함수)
# n()을 사용할때 dplyr::n()를 통해서 명시한다.
ex17 <- ex16 %>% group_by(quarter) %>% summarise(평균 = mean(총생산량), 불량품총합 = sum(불량품), 불량품도수 = dplyr::n())
ex17