16. dplyr 패키지 실습


r

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





© 2019. by RaP0d

Powered by aiden