dplyr 함수들을 조합한 실전 데이터 다루기 3
데이터 불러오기
변수명도 변경하기 데이터를 불러오고 변수명을 변경하는 법은 앞의 강의들을 참조해주기바란다. 대신 코드는 올린다. 판매 데이터, 업종 코드 데이터, 강수량이 들어있는 기후 데이터를 다 불러오고 변수명을 영문으로 변경하였다.
sales <- read.csv('sales.csv', stringsAsFactors = F,
fileEncoding = 'UTF-8')
colnames(sales) <- c('city', 'district', 'gender', 'sales.nm', 'sales.cd', 'ymd', 'sales.num')
products <- read.csv("productcode.csv", stringsAsFactors = F,
fileEncoding = "UTF-8")
colnames(products) <- c('products.cd', 'products.nm')
climates <- read.csv('seoul_climate.csv', stringsAsFactors = F,
fileEncoding = 'UTF-8')
colnames(climates) <- c('city', 'district', 'ym', 'lat', 'lon', 'rainfall')
판매 데이터에 업종 데이터와 join
mutate
판매 데이터에 업종 데이터와 join 하기 위해 변수를 생성한다.
두 데이터를 합치려면 동일한 업종코드products.cd
가 판매 데이터에 있으면 키로 두 데이터를 합칠 수 있다. 그런데 판매 데이터에는 업종코드가 없다. 그래서 mutate를 이용하여 products.cd를 생성하여 join을 해주자.
sales <- sales %>%
mutate(products.cd = substr(sales.cd, 1, 4))
판매 데이터에 업종 데이터와 join
그 이후에 left join을 해 판매 데이터를 확인하면 업종 코드가 있는 것을 알 수 있다.
sales <- sales %>%
mutate(products.cd = substr(sales.cd, 1, 4))
sales <- left_join(sales, products)
sales %>% head
Joining, by = "products.cd"
city district gender sales.nm sales.cd ymd sales.num products.cd 1 서울특별시 강남구 남 스탑버스 12AA02 20140101 103 12AA 2 서울특별시 강남구 여 키즈랜드 100101 20140101 309 1001 3 서울특별시 강남구 여 키즈랜드 100101 20140101 365 1001 4 서울특별시 강남구 남 스탑버스 12AA02 20140101 421 12AA 5 서울특별시 강남구 여 스탑버스 12AA02 20140101 413 12AA 6 서울특별시 강남구 남 키즈랜드 100101 20140101 428 1001 products.nm 1 카페 2 유아용품 3 유아용품 4 카페 5 카페 6 유아용품
mutate
판매 데이터에 기후 데이터와 join 하기 위해 변수를 생성한다. 마찬가지로 기후 데이터에 연월 이라는 변수를 추가해주자.
sales <- sales %>%
mutate(ym = substr(ymd, 1, 6))
as.character
기후 데이터에서는 연월 변수가 숫자로 되어있어서 as.character
로 변환하자.
climates$ym <- as.character(climates$ym)
판매 데이터에 기후 데이터와 join
sales <- sales %>%
mutate(products.cd = substr(sales.cd, 1, 4))
sales <- left_join(sales, products)
sales %>% head
sales <- sales %>%
mutate(ym = substr(ymd, 1, 6))
climates$ym <- as.character(climates$ym)
sales <- left_join(sales, climates)
sales %>% head
Joining, by = c("products.cd", "products.nm")
city district gender sales.nm sales.cd ymd sales.num products.cd 1 서울특별시 강남구 남 스탑버스 12AA02 20140101 103 12AA 2 서울특별시 강남구 여 키즈랜드 100101 20140101 309 1001 3 서울특별시 강남구 여 키즈랜드 100101 20140101 365 1001 4 서울특별시 강남구 남 스탑버스 12AA02 20140101 421 12AA 5 서울특별시 강남구 여 스탑버스 12AA02 20140101 413 12AA 6 서울특별시 강남구 남 키즈랜드 100101 20140101 428 1001 products.nm ym 1 카페 201401 2 유아용품 201401 3 유아용품 201401 4 카페 201401 5 카페 201401 6 유아용품 201401
Joining, by = c("city", "district", "ym")
city district gender sales.nm sales.cd ymd sales.num products.cd 1 서울특별시 강남구 남 스탑버스 12AA02 20140101 103 12AA 2 서울특별시 강남구 여 키즈랜드 100101 20140101 309 1001 3 서울특별시 강남구 여 키즈랜드 100101 20140101 365 1001 4 서울특별시 강남구 남 스탑버스 12AA02 20140101 421 12AA 5 서울특별시 강남구 여 스탑버스 12AA02 20140101 413 12AA 6 서울특별시 강남구 남 키즈랜드 100101 20140101 428 1001 products.nm ym lat lon rainfall 1 카페 201401 37.49666 127.063 NA 2 유아용품 201401 37.49666 127.063 NA 3 유아용품 201401 37.49666 127.063 NA 4 카페 201401 37.49666 127.063 NA 5 카페 201401 37.49666 127.063 NA 6 유아용품 201401 37.49666 127.063 NA
1번 문제
업종별(products.nm) 평균 판매건수를 구하세요. 단, NA 업종은 제외하세요.
group_by, filter, summarise
group_by
를 하고, NA
를 제외하기 위해 filter
를 한다. filter
를 뒤에 하든 앞에 하든 상관없는데 보통 앞에 하는게 좋다. 그리고 summarise
를 하여 평균 판매건수를 구한다.
sales %>%
filter(!is.na(products.nm)) %>%
group_by(products.nm) %>%
summarise(mean.sales.num = mean(sales.num, na.rm = T))
products.nm mean.sales.num 1 완구 250.7495 2 유아용품 249.8582 3 카페 250.0636 4 한식 250.7960
2번 문제
한식 업종의 월별 평균 판매건수를 구하고, 내림차순으로 정렬을 하세요.
filter
위와 다른 것은 월별로 구하는 것이 필요하고 한식
업종만 구하면 된다.
sales %>%
filter(products.nm == '한식')
city district gender sales.nm sales.cd ymd sales.num 1 서울특별시 강남구 남 원조한식 100201 20140101 363 2 서울특별시 강남구 남 원조백반 100202 20140101 480 3 서울특별시 강남구 여 원조백반 100202 20140101 25 4 서울특별시 강남구 여 전주비빔 100203 20140101 415 ...
mutate
그 다음에 월별이라 했는데 월 변수가 없기 때문에 mutate
로 월 변수를 구한다.
sales %>%
filter(products.nm == '한식') %>%
mutate(m = substr(ymd, 5, 6))
city district gender sales.nm sales.cd ymd sales.num 1 서울특별시 강남구 남 원조한식 100201 20140101 363 2 서울특별시 강남구 남 원조백반 100202 20140101 480 3 서울특별시 강남구 여 원조백반 100202 20140101 25 4 서울특별시 강남구 여 전주비빔 100203 20140101 415 ...
group_by, summarise
월별 판매 건수이니 group_by
가 들어가고 summarise
평균이 들어간다.
sales %>%
filter(products.nm == '한식') %>%
mutate(m = substr(ymd, 5, 6)) %>%
group_by(products.nm, m) %>%
summarise(mean.sales.num = mean(sales.num, na.rm = T))
products.nm m mean.sales.num 1 한식 01 253.7554 2 한식 02 252.7710 3 한식 03 250.3631 4 한식 04 249.7209 5 한식 05 251.9256 6 한식 06 250.1250 7 한식 07 249.2496 8 한식 08 249.2152 9 한식 09 253.0379 10 한식 10 246.7699 11 한식 11 252.1547 12 한식 12 250.6891
arrange
그 다음에 내림차순 정렬이니 desc
를 쓴 arrange
를 해주면 된다. 월별 평균 판매건수를 정렬해주면 된다.
sales %>%
filter(products.nm == '한식') %>%
mutate(m = substr(ymd, 5, 6)) %>%
group_by(products.nm, m) %>%
summarise(mean.sales.num = mean(sales.num, na.rm = T)) %>%
arrange(desc(mean.sales.num))
products.nm m mean.sales.num 1 한식 01 253.7554 2 한식 09 253.0379 3 한식 02 252.7710 4 한식 11 252.1547 5 한식 05 251.9256 6 한식 12 250.6891 7 한식 03 250.3631 8 한식 06 250.1250 9 한식 04 249.7209 10 한식 07 249.2496 11 한식 08 249.2152 12 한식 10 246.7699
3번 문제
매출데이터에서 월별 & 구별 & 업종(products.nm)별 평균 판매 건수와 평균 강수량을 구하세요. 단, 평균 판매 건수와 평균 강수량이 NA
인 것은 제외하세요.
판매 데이터에 월 변수가 없기 때문에 mutate
을 사용해 월 변수를 만들고, group_by
를 사용하여 월별 구별 업종별이 다 들어가기 때문에 넣어준다.
그리고 summarise
를 하여 평균 판매건수, 평균 강수량을 구한다.
sales %>%
mutate(m = substr(ymd, 5, 6)) %>%
group_by(m, district, products.nm) %>%
summarise(mean.sales.num = mean(sales.num, na.rm = T),
mean.rainfall = mean(rainfall, na.rm = T))
m district products.nm mean.sales.num mean.rainfall 1 01 강남구 NA 275.4787 NaN 2 01 강남구 완구 239.6862 NaN 3 01 강남구 유아용품 266.5385 NaN 4 01 강남구 카페 249.7489 NaN ...
NA 처리
코드 뒤에 filter
를 하여 is.na
로 평균 판매건수와 평균 강수량에서 NA
값을 제외한다.
sales %>%
mutate(m = substr(ymd, 5, 6)) %>%
group_by(m, district, products.nm) %>%
summarise(mean.sales.num = mean(sales.num, na.rm = T),
mean.rainfall = mean(rainfall, na.rm = T)) %>%
filter(!is.na(mean.sales.num) & !is.na(mean.rainfall))
m district products.nm mean.sales.num mean.rainfall 1 01 강북구 NA 254.6341 0 2 01 강북구 완구 250.7737 0 3 01 강북구 유아용품 230.0101 0 4 01 강북구 카페 271.1531 0 ...
4번 문제
3번의 결과에서 평균 강수량mean.rainfall
을 250 이상은 '상', 50 ~ 250은 '중', 50미만은 '하'로 바꾸어 새로운 변수에 저장하세요.
mutate, ifelse
위의 코드를 붙여놓고 mutate
로 새로운 변수를 만들어준다. 조건이 들어가기 때문에 ifelse
를 사용한다. 250보다 크면 '상', 그게 아닐 때는 조건을 하나 더 줄 수 있다. 250보다 작은 경우에 한해서 50보다 크면 '중' 아니면 '하'로 한다.
sales %>%
mutate(m = substr(ymd, 5, 6)) %>%
group_by(m, district, products.nm) %>%
summarise(mean.sales.num = mean(sales.num, na.rm = T),
mean.rainfall = mean(rainfall, na.rm = T)) %>%
filter(!is.na(mean.sales.num) & !is.na(mean.rainfall)) %>%
mutate(rainfall.grade = ifelse(mean.rainfall >= 250, '상',
ifelse(mean.rainfall >= 50, '중', '하')))
m district products.nm mean.sales.num mean.rainfall rainfall.grade 1 01 강북구 NA 254.6341 0 하 2 01 강북구 완구 250.7737 0 하 3 01 강북구 유아용품 230.0101 0 하 4 01 강북구 카페 271.1531 0 하 ...
5번 문제
4번 결과에서 평균 강수량 등급(rainfall.grade) 별 평균 판매건수(mean.sales.num)의 평균을 다시 구해보세요.
group_by, summarise
강수량 등급rainfall.grade
을 group_by
로 묶어주고 summarise
로 평균 판매건수와 강수량을 구한다.
sales %>%
mutate(m = substr(ymd, 5, 6)) %>%
group_by(m, district, products.nm) %>%
summarise(mean.sales.num = mean(sales.num, na.rm = T),
mean.rainfall = mean(rainfall, na.rm = T)) %>%
filter(!is.na(mean.sales.num) & !is.na(mean.rainfall)) %>%
mutate(rainfall.grade = ifelse(mean.rainfall >= 250, '상',
ifelse(mean.rainfall >= 50, '중', '하'))) %>%
group_by(rainfall.grade) %>%
summarise(mean.mean.sales.num = mean(mean.sales.num, na.rm = T))
rainfall.grade mean.mean.sales.num 1 상 248.6016 2 중 250.7814 3 하 250.9025
코드를 효과적으로 짜기
3번을 mean.sales
변수에 저장하고 거기에 chain을 하여 뒷 단계를 할 수 있다.
mean.sales <- sales %>%
mutate(m = substr(ymd, 5, 6)) %>%
group_by(m, district, products.nm) %>%
summarise(mean.sales.num = mean(sales.num, na.rm = T),
mean.rainfall = mean(rainfall, na.rm = T)) %>%
filter(!is.na(mean.sales.num) & !is.na(mean.rainfall))
변수를 만들고 다시한번 밑에서 작업을 해도 큰 무리가 없다.
mean.sales %>%
mutate(rainfall.grade = ifelse(mean.rainfall >= 250, '상',
ifelse(mean.rainfall >= 50, '중', '하'))) %>%
group_by(rainfall.grade) %>%
summarise(mean.mean.sales.num = mean(mean.sales.num, na.rm = T))
rainfall.grade mean.mean.sales.num 1 상 248.6016 2 중 250.7814 3 하 250.9025