KDX Competition Guideline
Page content
개요
- 본 수업을 듣는 수강생들을 위해 간단한 튜토리얼을 만들었다.
- 대회는 다음과 같다.
- 싸이트: 한국데이터거래소
/img/r/competition/blog_kdx_guideline_files/img
1단계 패키지 불러오기
- 데이터 가공 및 시각화 위주의 패키지를 불러온다.
library(tidyverse) # 데이터 가공 및 시각화
library(readxl) # 엑셀파일 불러오기 패키지
2단계 데이터 불러오기
- 데이터가 많아서 순차적으로 진행하도록 한다.
- 각 데이터에 대한 설명은
활용데이터설명(PDF)
을 참조한다.
- 먼저 제 개발환경은 아래와 같다.
- Note: 윈도우와 Mac은 다를 수 있음을 명심하자.
sessionInfo()
## R version 4.0.2 (2020-06-22)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Catalina 10.15.6
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] readxl_1.3.1 forcats_0.5.0 stringr_1.4.0 dplyr_1.0.0
## [5] purrr_0.3.4 readr_1.3.1 tidyr_1.1.0 tibble_3.0.3
## [9] ggplot2_3.3.2 tidyverse_1.3.0
##
## loaded via a namespace (and not attached):
## [1] Rcpp_1.0.5 cellranger_1.1.0 pillar_1.4.6 compiler_4.0.2
## [5] dbplyr_1.4.4 tools_4.0.2 digest_0.6.25 lubridate_1.7.9
## [9] jsonlite_1.7.0 evaluate_0.14 lifecycle_0.2.0 gtable_0.3.0
## [13] pkgconfig_2.0.3 rlang_0.4.7 reprex_0.3.0 cli_2.0.2
## [17] rstudioapi_0.11 DBI_1.1.0 yaml_2.2.1 haven_2.3.1
## [21] xfun_0.16 withr_2.3.0 xml2_1.3.2 httr_1.4.2
## [25] knitr_1.29 fs_1.5.0 hms_0.5.3 generics_0.0.2
## [29] vctrs_0.3.2 grid_4.0.2 tidyselect_1.1.0 glue_1.4.1
## [33] R6_2.4.1 fansi_0.4.1 rmarkdown_2.3 modelr_0.1.8
## [37] blob_1.2.1 magrittr_1.5 backports_1.1.8 scales_1.1.1
## [41] ellipsis_0.3.1 htmltools_0.5.0 rvest_0.3.6 assertthat_0.2.1
## [45] colorspace_1.4-1 stringi_1.4.6 munsell_0.5.0 broom_0.7.0
## [49] crayon_1.3.4
(1) 삼성카드 데이터
- 우선 삼성카드 데이터를 불러와서 확인한다.
- 한글 파일은 인코딩이 늘 항상 문제다.
- 파일을 불러오기 전 항상 파일 인코딩을 확인하도록 한다.
readr::guess_encoding("data/Samsungcard.csv", n_max = 100)
## # A tibble: 2 x 2
## encoding confidence
## <chr> <dbl>
## 1 EUC-KR 1
## 2 GB18030 0.62
- Encoding 확인 결과
EUC-KR
로 확인하였다.
samsung_card <- read_xlsx("data/Samsungcard.xlsx")
samsung_card2 <- read.csv("data/Samsungcard.csv", fileEncoding = "EUC-KR")
- 위 두 파일이 동일한 것을 확인해본다
head(samsung_card)
## # A tibble: 6 x 5
## 소비일자 소비업종 성별 연령대 소비건수
## <dbl> <chr> <chr> <chr> <dbl>
## 1 20190101 가전/가구 남성 20대 5529
## 2 20190101 가전/가구 남성 30대 17536
## 3 20190101 가전/가구 남성 40대 22838
## 4 20190101 가전/가구 남성 50대 15801
## 5 20190101 가전/가구 남성 60대 6772
## 6 20190101 가전/가구 여성 20대 5937
head(samsung_card2)
## 소비일자 소비업종 성별 연령대 소비건수
## 1 20190101 가전/가구 남성 20대 5529
## 2 20190101 가전/가구 남성 30대 17536
## 3 20190101 가전/가구 남성 40대 22838
## 4 20190101 가전/가구 남성 50대 15801
## 5 20190101 가전/가구 남성 60대 6772
## 6 20190101 가전/가구 여성 20대 5937
- 두 파일이 동일한 것을 확인하였다면 이제
samsung_card2
는 삭제를 한다.RAM
을 아껴 쓰자.
rm(samsung_card2) # 객체 지우는 함수
ls() # 현재 저장된 객체 확인하는 함수
## [1] "samsung_card"
(2) 신한카드 데이터
- 이번에는
ShinhanCard.xslx
데이터를 불러온다.
shinhancard <- read_xlsx("data/Shinhancard.xlsx")
head(shinhancard)
## # A tibble: 6 x 8
## 일별 성별 연령대별 업종 `카드이용건수(천건)`… ...6 ...7 ...8
## <chr> <chr> <chr> <chr> <dbl> <lgl> <lgl> <dbl>
## 1 201901… F 20대 M001_한식 299. NA NA 10
## 2 201901… F 20대 M002_일식/중식/양식… 88.3 NA NA NA
## 3 201901… F 20대 M003_제과/커피/패스트푸드… 291. NA NA NA
## 4 201901… F 20대 M004_기타요식 446. NA NA NA
## 5 201901… F 20대 M005_유흥 24.2 NA NA NA
## 6 201901… F 20대 M006_백화점 35.3 NA NA NA
- 위 데이터를 불러오니 불필요한
6:8
변수가 불러온 것을 확인할 수 있다.- 실제 엑셀 데이터를 열어도 빈값임을 확인할 수 있다.
- 따라서,
6:8
변수는 삭제한다.
shinhancard <- shinhancard %>%
select(-c(6:8))
head(shinhancard)
## # A tibble: 6 x 5
## 일별 성별 연령대별 업종 `카드이용건수(천건)`
## <chr> <chr> <chr> <chr> <dbl>
## 1 20190101 F 20대 M001_한식 299.
## 2 20190101 F 20대 M002_일식/중식/양식 88.3
## 3 20190101 F 20대 M003_제과/커피/패스트푸드 291.
## 4 20190101 F 20대 M004_기타요식 446.
## 5 20190101 F 20대 M005_유흥 24.2
## 6 20190101 F 20대 M006_백화점 35.3
(3) 지인플러스
- 지인플러스는 아파트시세(
GIN00009A
)와 아파트 거래량(GIN00008B
)을 담은 코드이다.
gin_8a <- read_csv("data/GIN00008A.csv")
gin_9a <- read_csv("data/GIN00009A.csv")
- 위 두개의 데이터를 확인해본다.
glimpse(gin_8a)
## Rows: 937,904
## Columns: 9
## $ ym <dbl> 200601, 200602, 200603, 200604, 200605, 200606, 200607…
## $ area_lvl_scor <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ lgdng_cd <chr> "0000000000", "0000000000", "0000000000", "0000000000"…
## $ trd_cont <dbl> 23357, 38617, 52241, 44253, 41916, 30257, 28613, 37362…
## $ avg_trd_cont <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ trd_deal_rat <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ mtrnt_cont <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ avg_mtrnt_cont <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ mtrnt_deal_rat <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
glimpse(gin_9a)
## Rows: 785,805
## Columns: 4
## $ lgdng_cd <dbl> 1.1e+09, 1.1e+09, 1.1e+09, 1.1e+09, 1.1e+09, 1.1e+09, 1.1e+0…
## $ std_date <date> 2006-01-21, 2006-02-21, 2006-03-21, 2006-04-21, 2006-05-21,…
## $ trd_prc <dbl> 1289, 1271, 1291, 1307, 1321, 1335, 1357, 1381, 1411, 1444, …
## $ ldpb_prc <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
(4) JSON 파일 불러오기
JSON
파일 불러올 때에는jsonlite
패키지를 활용한다.
library(jsonlite)
GIN_10m <- fromJSON("data/center_GIN00010M.json")
glimpse(GIN_10m)
## Rows: 20,572
## Columns: 8
## $ AREA_LVL_SCOR <int> 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3…
## $ LGDNG_CD <chr> "1100000000", "1111000000", "1111010100", "1111010200",…
## $ CTPV_NM <chr> "서울특별시", "서울특별시", "서울특별시", "서울특별시", "서울특별시", "서울특별시", "…
## $ CTGG_NM <chr> NA, "종로구", "종로구", "종로구", "종로구", "종로구", "종로구", "종로구", "종…
## $ EMD_NM <chr> NA, NA, "청운동", "신교동", "궁정동", "효자동", "창성동", "통의동", "적선동"…
## $ LA <dbl> 37.52934, 37.58586, 37.58920, 37.58449, 37.58468, 37.58…
## $ LNGT <dbl> 126.9515, 126.9775, 126.9693, 126.9679, 126.9731, 126.9…
## $ PYN_CN <chr> "{\"type\": \"Polygon\", \"coordinates\": [[[126.979658…
PYN_CN
의 값이 조금 다른 것을 확인할 수 있다.- 이 부분은 추후 전처리할 때 정리하는 것으로 확인한다.
(5) SSC_Data
- 이번에는
Mcorporation
내 폴더 데이터를 올리도록 한다. - 이번에 파일을 불러올 때는
readr::read_csv()
를 활용하여 불러온다.
readr::guess_encoding("data/Mcorporation/KDX시각화경진대회_SSC_DATA.csv")
## # A tibble: 2 x 2
## encoding confidence
## <chr> <dbl>
## 1 EUC-KR 1
## 2 GB18030 0.76
ssc_data <- read_csv("data/Mcorporation/KDX시각화경진대회_SSC_DATA.csv", locale = locale("ko", encoding = "EUC-KR"))
glimpse(ssc_data)
## Rows: 76,580
## Columns: 5
## $ 소비일자 <dbl> 20190101, 20190101, 20190101, 20190101, 20190101, 20190101, 2019…
## $ 소비업종 <chr> "가전/가구", "가전/가구", "가전/가구", "가전/가구", "가전/가구", "가전/가구", "가전/가구", "…
## $ 성별 <chr> "남성", "남성", "남성", "남성", "남성", "여성", "여성", "여성", "여성", "여성", "남…
## $ 연령대 <chr> "20대", "30대", "40대", "50대", "60대", "20대", "30대", "40대", "50대", …
## $ 소비건수 <dbl> 5529, 17536, 22838, 15801, 6772, 5937, 12895, 16896, 14025, 5909…
(6) 다중 엑셀파일 불러오기 예제
상품 카데고리 데이터_KDX
시각화 폴더 내 엑셀 데이터를 확인해본다.
list.files(path = "data/Mcorporation/상품 카테고리 데이터_KDX 시각화 경진대회 Only/")
## [1] "PC사무기기.xlsx" "TV홈시어터.xlsx"
## [3] "가공식품.xlsx" "가방지갑잡화.xlsx"
## [5] "건강관련용품.xlsx" "건강식품.xlsx"
## [7] "계절가전.xlsx" "골프용품.xlsx"
## [9] "공구류.xlsx" "구기.xlsx"
## [11] "국내외여행.xlsx" "기타 스포츠.xlsx"
## [13] "낚시.xlsx" "남성의류.xlsx"
## [15] "노트북.xlsx" "농축수산물.xlsx"
## [17] "도서음반DVD.xlsx" "등산용품.xlsx"
## [19] "메이크업.xlsx" "문구사무용품.xlsx"
## [21] "미용가전.xlsx" "반려동물.xlsx"
## [23] "생활가구.xlsx" "생활가전.xlsx"
## [25] "생활용품.xlsx" "서비스티켓.xlsx"
## [27] "성인용품.xlsx" "세탁청소세면.xlsx"
## [29] "수납가구.xlsx" "수납용품.xlsx"
## [31] "수영.xlsx" "스키보드.xlsx"
## [33] "스킨케어.xlsx" "스포츠의류.xlsx"
## [35] "신발.xlsx" "악세서리시계주얼리.xlsx"
## [37] "안전용품.xlsx" "언더웨어.xlsx"
## [39] "업소위생용품.xlsx" "여성의류.xlsx"
## [41] "완구키덜트게임.xlsx" "욕실가전.xlsx"
## [43] "욕실용품.xlsx" "유아용품.xlsx"
## [45] "유아패션.xlsx" "음료.xlsx"
## [47] "음향가전.xlsx" "인테리어용품.xlsx"
## [49] "자동차용품.xlsx" "자전거사이클보드인라인.xlsx"
## [51] "주방가전.xlsx" "주방수납잡화.xlsx"
## [53] "주방식기용기.xlsx" "주방조리기구.xlsx"
## [55] "출산임부용품.xlsx" "취미악기.xlsx"
## [57] "침실가구.xlsx" "침실인테리어.xlsx"
## [59] "카메라캠코더.xlsx" "캠핑용품.xlsx"
## [61] "테마의류.xlsx" "헤어바디용품.xlsx"
## [63] "헬스기구용품.xlsx" "휴대폰악세서리.xlsx"
- 몇가지 파일을 열어본다.
- 엑셀 데이터의 변수 등이 동일한 것을 확인할 수 있다.
- 이제 위 데이터를 한꺼번에 불러와서 하나의 데이터셋으로 합친다.
- 검색키워드
Multiple Excel Files import in R
files <- list.files(path = "data/Mcorporation/상품 카테고리 데이터_KDX 시각화 경진대회 Only/", pattern = "*.xlsx", full.names = T)
products <- sapply(files, read_excel, simplify=FALSE) %>%
bind_rows(.id = "id") %>%
select(-id)
glimpse(products)
## Rows: 1,837,833
## Columns: 7
## $ 구매날짜 <dbl> 20190101, 20190101, 20190101, 20190101, 20190101, 20190101, 20…
## $ 카테고리명 <chr> "PC/사무기기", "PC/사무기기", "PC/사무기기", "PC/사무기기", "PC/사무기기", "PC/사무기기…
## $ 고객성별 <chr> "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F…
## $ 고객나이 <dbl> 10, 10, 10, 10, 20, 20, 20, 20, 30, 30, 30, 30, 40, 40, 40, 40…
## $ OS유형 <chr> "IOS", "WINDOWS", "안드로이드", "없음", "IOS", "WINDOWS", "안드로이드", …
## $ 구매금액 <dbl> 352443, 84000, 80870, 3700, 27714776, 11414514, 21223319, 4832…
## $ 구매수 <dbl> 13, 1, 8, 1, 381, 60, 252, 41, 240, 75, 423, 19, 58, 110, 436…
3단계 데이터 시각화
- 먼저, 데이터 저장 용량을 고려하여
products
데이터셋을 제외하고 나머지는 모두 삭제한다. - 데이터 시각화는 변수의 종류에 따른 시각화를 구현한 것이다.
- 시각화 참조자료는 다음에서 작성이 가능하다.
- 아래 샘플은 필자가 공부하는 형태를 구현한 것이다. 참조하기를 바란다.
(1) 수치형 변수 ~ 수치형 변수
- 수치형 변수 ~ 수치형 변수 시각화의 대표적인 기법은 산점도(
scatter
) 또는correlation
이라 부른다.scatter
시각화를 구현한다.
# load package and data
library(ggplot2)
data(mpg, package="ggplot2")
# mpg <- read.csv("http://goo.gl/uEeRGu")
# Scatterplot
theme_set(theme_bw()) # pre-set the bw theme.
g <- ggplot(mpg, aes(cty, hwy))
g + geom_count(col="tomato3", show.legend=F) +
labs(subtitle="mpg: city vs highway mileage",
y="hwy",
x="cty",
title="Counts Plot")
- 위 그래프를 작성한 뒤에는 반드시 데이터의 유형을 확인한다.
class(mpg$cty); class(mpg$hwy)
## [1] "integer"
## [1] "integer"
- 위 작업을 하는 이유는 현재 내 데이터에서 위 데이터 유형과 비슷한 것인지 확인하기 위한 것이다.
- 단 산점도를 시각화할 때 유의점이 있다. 데이터가 크기 때문에 시각화 구현에 시간이 소요된다.
- 이 때 필요한 방법론이 샘플링이다.
temp_products <- sample_n(products, 1000)
g <- ggplot(temp_products, aes(x = 구매수, y = 구매금액))
g + geom_count(col="tomato3", show.legend=F) +
labs(subtitle="products: count vs revenue ",
y="revenue",
x="count",
title="Counts Plot")
- 분명 동일한 시각화를 작성하였지만, 다르게 나왔다. 이럴 경우에는
x
+y
축에log Transformation
를 해준다.
g +
geom_count(col="tomato3", show.legend=F) +
scale_x_log10() +
scale_y_log10() +
labs(subtitle="products: count vs revenue ",
y="revenue",
x="count",
title="Counts Plot")
- 위 그래프를 보고 해석하는 것은 수강생들이 해야 하는 업무이다.
(2) 범주형 변수 ~ 수치형 변수
- 대표적인 방법으로는
boxplot
이 있다. - 그러나, 이번에는 카테고리명 기준으로 평균 구매금액의 평균을 구해본다. - 이번에도 마찬가지로 샘플을 보여준뒤 참조하는 형태로 작성한다.
cty_mpg <- aggregate(mpg$cty, by=list(mpg$manufacturer), FUN=mean)
colnames(cty_mpg) <- c("make", "mileage")
cty_mpg <- cty_mpg[order(cty_mpg$mileage), ]
cty_mpg$make <- factor(cty_mpg$make, levels = cty_mpg$make)
head(cty_mpg, 4)
## make mileage
## 9 lincoln 11.33333
## 8 land rover 11.50000
## 3 dodge 13.13514
## 10 mercury 13.25000
- 이렇게 정렬한 것을 시각화로 구현하는 것이다.
library(ggplot2)
theme_set(theme_bw())
# Draw plot
ggplot(cty_mpg, aes(x=make, y=mileage)) +
geom_bar(stat="identity", width=.5, fill="tomato3") +
labs(title="Ordered Bar Chart",
subtitle="Make Vs Avg. Mileage",
caption="source: mpg") +
theme(axis.text.x = element_text(angle=65, vjust=0.6))
- 이제 내 데이터에 확인해보자.
cat_rev <- aggregate(products$카테고리명, by=list(products$구매금액), FUN=mean)
- 위 코드를 실행하면 속도가 굉장히 더딘 것을 확인할 수 있다.
- 실제로
aggregate()
함수는 오래 걸린다.- 그래서
dplyr
를 활용하여 피벗테이블을 만든다.
- 그래서
library(ggplot2)
cat_rev <- products %>%
group_by(카테고리명) %>%
summarise(mean = mean(구매금액)) %>%
arrange(desc(mean))
cat_rev <- cat_rev[order(cat_rev$mean, decreasing = TRUE), ] # sort
cat_rev$카테고리명 <- factor(cat_rev$카테고리명, levels = cat_rev$카테고리명) # to retain the order in plot.
head(cat_rev)
## # A tibble: 6 x 2
## 카테고리명 mean
## <fct> <dbl>
## 1 도서/음반/DVD 93366896.
## 2 서비스/티켓 89818959.
## 3 여성의류 62282167.
## 4 신발 58230514.
## 5 가공식품 48249770.
## 6 PC/사무기기 30909343.
- 이제 위 데이터를 시각화 해본다.
# 맥 유저만 아래 코드 적용
theme_set(theme_classic(base_family='NanumGothic'))
ggplot(cat_rev %>% head(20), aes(x = 카테고리명, y = mean)) +
geom_bar(stat="identity", width=.5, fill="tomato3") +
theme(axis.text.x = element_text(angle=65, vjust=0.6)) +
labs(title="Ordered Bar Chart",
subtitle="카테고리명 Vs Avg. 구매금액",
caption="source: products")
category_list <- cat_rev$카테고리명
category_list
## [1] 도서/음반/DVD 서비스/티켓
## [3] 여성의류 신발
## [5] 가공식품 PC/사무기기
## [7] 농축수산물 가방/지갑/잡화
## [9] 메이크업 용품 국내외여행
## [11] 건강식품 남성의류
## [13] 문구/사무용품 스포츠의류/잡화
## [15] 주방가전 계절가전
## [17] 음료 악세서리/시계/주얼리
## [19] 생활 가전 반려동물용품
## [21] 완구/키덜트/게임 인테리어용품
## [23] 휴대폰/악세서리 생활 가구
## [25] 유아/아동용품 세탁/청소/세면 용품
## [27] 공구류 취미/악기
## [29] 유아/아동의류 건강 관련용품
## [31] 침실 인테리어 헤어/바디케어
## [33] 주방식기/용기 노트북/태블릿/학습가전
## [35] 스킨케어 생활용품
## [37] 침실 가구 언더웨어
## [39] TV/홈시어터 주방조리기구
## [41] 미용가전/안마기 골프용품
## [43] 음향가전 자동차 관련용품
## [45] 주방수납/잡화 안전용품
## [47] 카메라/캠코더 수납용품
## [49] 캠핑용품 등산용품
## [51] 자전거/사이클/보드/인라인 기타 스포츠/스포츠 용품
## [53] 욕실가전 수영용품
## [55] 출산용품/임부용품 욕실용품
## [57] 구기종목 용품 헬스기구용품
## [59] 낚시용품 수납가구
## [61] 테마의류 업소 위생용품
## [63] 성인용품 스키/보드용품
## 64 Levels: 도서/음반/DVD 서비스/티켓 여성의류 신발 가공식품 ... 스키/보드용품
-
위
list
추후 작성을 위해list
로 남겨 놓는다. -
이번에는 카테고리명 ~ 평균 구매건수에 관한 시각화를 작성해본다.
-
해석은 각자 진행하고 반영하면 된다.
(3) 위 두 그래프 확장하기
- 성별 및 연령대별로 추가적인 변수를 넣어 확인해보는 시각화를 만들어 본다.
- 먼저 성별을 기준으로 산점도를 작성해본다.
temp_products <- sample_n(products, 1000)
g <- ggplot(temp_products, aes(x = 구매수, y = 구매금액))
# g + geom_count(col="tomato3", show.legend=F) +
g + geom_point(aes(colour = 고객성별)) +
scale_x_log10() +
scale_y_log10() +
labs(subtitle="products: count vs revenue ",
y="revenue",
x="count",
title="Counts Plot")
- 상대적으로 시각화 눈에 잘 들어오지 않는다.
- 이러한 경우
facet_()
함수 계열을 활용해본다.
- 이러한 경우
g <- ggplot(temp_products, aes(x = 구매수, y = 구매금액))
# g + geom_count(col="tomato3", show.legend=F) +
g + geom_point(col="tomato3") +
scale_x_log10() +
scale_y_log10() +
facet_grid(고객성별 ~.) +
labs(subtitle="products: count vs revenue ",
y="revenue",
x="count",
title="Counts Plot")
없음
의 값이 상대적으로 작기 때문에 해당 영역은 제외하고 데이터셋을 재구성한다.- 이 때,
filter()
함수를 활용한다.
gender_products <- products %>%
filter(고객성별 != "없음")
dim(products); dim(gender_products)
## [1] 1837833 7
## [1] 1732078 7
- 약 10만개의 데이터가 줄어든 것을 확인할 수 있다.
temp_products <- sample_n(gender_products, 1000)
g <- ggplot(temp_products, aes(x = 구매수, y = 구매금액))
# g + geom_count(col="tomato3", show.legend=F) +
g + geom_point(col="tomato3") +
scale_x_log10() +
scale_y_log10() +
facet_grid(고객성별 ~.) +
labs(subtitle="products: count vs revenue ",
y="revenue",
x="count",
title="Counts Plot")
- 훨씬 더 시각적으로 비교가 잘 되는 것을 확인할 수 있다.
- 이번에는 막대 그래프를 추가해본다.
cat_rev <- products %>%
group_by(카테고리명, 고객성별) %>%
summarise(mean = mean(구매금액)) %>%
arrange(desc(mean))
glimpse(cat_rev)
## Rows: 192
## Columns: 3
## Groups: 카테고리명 [64]
## $ 카테고리명 <chr> "도서/음반/DVD", "서비스/티켓", "신발", "PC/사무기기", "문구/사무용품", "가공식품", "여성의…
## $ 고객성별 <chr> "없음", "없음", "없음", "없음", "없음", "없음", "없음", "F", "없음", "F", "없음"…
## $ mean <dbl> 376868009, 308278103, 243189502, 212857790, 174581259, 143…
cat_rev <- cat_rev[order(cat_rev$mean, decreasing = TRUE), ] # sort
cat_rev
## # A tibble: 192 x 3
## # Groups: 카테고리명 [64]
## 카테고리명 고객성별 mean
## <chr> <chr> <dbl>
## 1 도서/음반/DVD 없음 376868009.
## 2 서비스/티켓 없음 308278103.
## 3 신발 없음 243189502.
## 4 PC/사무기기 없음 212857790.
## 5 문구/사무용품 없음 174581259.
## 6 가공식품 없음 143698037.
## 7 여성의류 없음 117868620.
## 8 여성의류 F 100027424.
## 9 공구류 없음 96215460.
## 10 도서/음반/DVD F 90766413.
## # … with 182 more rows
- 위 데이터를 보면 알겠지만,
없음
이 데이터의 비율이 높게 형성된 것을 확인할 수 있다. - 이는 마케팅 기획에 있어서 적합하지 않을 뿐 아니라 데이터의 상대적으로 적기 때문에 제거한다.
cat_rev2 <- cat_rev %>%
filter(고객성별 != "없음")
cat_rev2
## # A tibble: 128 x 3
## # Groups: 카테고리명 [64]
## 카테고리명 고객성별 mean
## <chr> <chr> <dbl>
## 1 여성의류 F 100027424.
## 2 도서/음반/DVD F 90766413.
## 3 서비스/티켓 F 82775484.
## 4 서비스/티켓 M 75524898.
## 5 도서/음반/DVD M 68399900.
## 6 가공식품 F 58375598.
## 7 신발 F 55024533.
## 8 신발 M 43104913.
## 9 메이크업 용품 F 38278015.
## 10 가방/지갑/잡화 F 38144345.
## # … with 118 more rows
ggplot(cat_rev2, aes(x = 카테고리명, y = mean, fill = 고객성별)) +
geom_bar(stat="identity", position = "dodge", width=.5)
- 데이터의 값이 많다보니 카테고리를 구분해서 보도록 한다.
i = 1
j = i+7
category_list <- as.character(category_list)
cat_rev2 %>%
filter(카테고리명 %in% category_list[c(i:as.numeric(i+7))]) %>%
ggplot(aes(x = 카테고리명, y = mean, fill = 고객성별)) +
geom_bar(stat="identity", position = "dodge", width=.5) +
theme(axis.text.x = element_text(angle=65, vjust=0.6)) +
labs(title="Ordered Bar Chart",
subtitle="카테고리명 Vs Avg. 구매금액 by 고객성별",
caption="source: products")
category_graph <- function(df, cat_list = cat_list) {
category_list <- sort(as.character(cat_list))
print(category_list)
for (i in seq(1, 64, by = 8)) {
i = i
j = i+7
plot <- df %>%
filter(카테고리명 %in% category_list[i:j]) %>%
ggplot(aes(x = 카테고리명, y = mean, fill = 고객성별)) +
geom_bar(stat="identity", position = "dodge", width=.5) +
theme(axis.text.x = element_text(angle=65, vjust=0.6)) +
labs(title="Ordered Bar Chart",
subtitle="카테고리명 Vs Avg. 구매금액 by 고객성별",
caption="source: products")
print(plot)
}
}
category_graph(cat_rev2, category_list)
## [1] "PC/사무기기" "TV/홈시어터"
## [3] "가공식품" "가방/지갑/잡화"
## [5] "건강 관련용품" "건강식품"
## [7] "계절가전" "골프용품"
## [9] "공구류" "구기종목 용품"
## [11] "국내외여행" "기타 스포츠/스포츠 용품"
## [13] "낚시용품" "남성의류"
## [15] "노트북/태블릿/학습가전" "농축수산물"
## [17] "도서/음반/DVD" "등산용품"
## [19] "메이크업 용품" "문구/사무용품"
## [21] "미용가전/안마기" "반려동물용품"
## [23] "생활 가구" "생활 가전"
## [25] "생활용품" "서비스/티켓"
## [27] "성인용품" "세탁/청소/세면 용품"
## [29] "수납가구" "수납용품"
## [31] "수영용품" "스키/보드용품"
## [33] "스킨케어" "스포츠의류/잡화"
## [35] "신발" "악세서리/시계/주얼리"
## [37] "안전용품" "언더웨어"
## [39] "업소 위생용품" "여성의류"
## [41] "완구/키덜트/게임" "욕실가전"
## [43] "욕실용품" "유아/아동용품"
## [45] "유아/아동의류" "음료"
## [47] "음향가전" "인테리어용품"
## [49] "자동차 관련용품" "자전거/사이클/보드/인라인"
## [51] "주방가전" "주방수납/잡화"
## [53] "주방식기/용기" "주방조리기구"
## [55] "출산용품/임부용품" "취미/악기"
## [57] "침실 가구" "침실 인테리어"
## [59] "카메라/캠코더" "캠핑용품"
## [61] "테마의류" "헤어/바디케어"
## [63] "헬스기구용품" "휴대폰/악세서리"
가나다
순으로카테고리
별시각화
를 구현한 뒤,고객성별
로 비교할 수 있다.- 카테고리, 고객성별 대신에, 고객나이, OS유형 등을 조합해서 시각화를 작성한 뒤 비교하는 것은 수강생들에게 남겨둔다.
(4) 시계열 그래프
- 이번에는 시계열 그래프를 작성한다.
- 마찬가지로 Top 50 ggplot2 Visualizations - The Master List (With Full R Code)에서 시각화를 선 구현한 뒤, 본 그래프를 작성해본다.
library(ggplot2)
# Compute % Returns
economics$returns_perc <- c(0, diff(economics$psavert)/economics$psavert[-length(economics$psavert)])
# Allow Default X Axis Labels
ggplot(economics, aes(x=date)) +
geom_line(aes(y=returns_perc)) +
labs(title="Time Series Chart",
subtitle="Returns Percentage from 'Economics' Dataset",
caption="Source: Economics",
y="Returns %")
glimpse(economics)
## Rows: 574
## Columns: 7
## $ date <date> 1967-07-01, 1967-08-01, 1967-09-01, 1967-10-01, 1967-11…
## $ pce <dbl> 506.7, 509.8, 515.6, 512.2, 517.4, 525.1, 530.9, 533.6, …
## $ pop <dbl> 198712, 198911, 199113, 199311, 199498, 199657, 199808, …
## $ psavert <dbl> 12.6, 12.6, 11.9, 12.9, 12.8, 11.8, 11.7, 12.3, 11.7, 12…
## $ uempmed <dbl> 4.5, 4.7, 4.6, 4.9, 4.7, 4.8, 5.1, 4.5, 4.1, 4.6, 4.4, 4…
## $ unemploy <dbl> 2944, 2945, 2958, 3143, 3066, 3018, 2878, 3001, 2877, 27…
## $ returns_perc <dbl> 0.000000000, 0.000000000, -0.055555556, 0.084033613, -0.…
- 여기서 주목해야 하는 것은
date
의 객체가date
라는 것이다.
class(economics$date)
## [1] "Date"
- 그런데, 만약
date
의 형태가 다르면 어떻게 해야할까? - 그럼 변환해야 한다.
- 간단한 예시로 확인한다. (기본 문법)
temp_date <- "20200110"
conv_date <- as.Date(temp_date, format = "%Y%m%d")
print(conv_date)
## [1] "2020-01-10"
class(conv_date)
## [1] "Date"
-
그런데,
%Y%m%d
는 무엇일까? 보다 쉽게 정리할 수 있는 패키지는 없을까? -
위 내용은 다음에서 확인한다.
- 시간(날짜)형태의 변수 다루기: 기본문법을 활용하여 날짜 데이터를 다룬다.
- R에서 깔끔하게 날짜-시간 데이터 처리하기(feat. lubridate):
lubridate
패키지를 활용하여 날짜 데이터를 처리할 수 있다.
-
이제 실제 데이터를 활용하여 시각화를 시계열 데이터를 똑같이 만들어 본다.
glimpse(shinhancard)
## Rows: 195,599
## Columns: 5
## $ 일별 <chr> "20190101", "20190101", "20190101", "20190101", "2…
## $ 성별 <chr> "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", …
## $ 연령대별 <chr> "20대", "20대", "20대", "20대", "20대", "20대", "20대", "20…
## $ 업종 <chr> "M001_한식", "M002_일식/중식/양식", "M003_제과/커피/패스트푸드", "M…
## $ `카드이용건수(천건)` <dbl> 298.9, 88.3, 290.6, 446.3, 24.2, 35.3, 388.0, 557.5, 36.…
- 위 데이터에서 보는 것처럼
일별
이 있지만,<chr>
문자열로 기록되는 것을 확인할 수 있다. - 이 데이터를 변환한다.
shinhancard$일별 <- as.Date(shinhancard$일별, format = "%Y%m%d")
glimpse(shinhancard)
## Rows: 195,599
## Columns: 5
## $ 일별 <date> 2019-01-01, 2019-01-01, 2019-01-01, 2019-01-01, 2…
## $ 성별 <chr> "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", …
## $ 연령대별 <chr> "20대", "20대", "20대", "20대", "20대", "20대", "20대", "20…
## $ 업종 <chr> "M001_한식", "M002_일식/중식/양식", "M003_제과/커피/패스트푸드", "M…
## $ `카드이용건수(천건)` <dbl> 298.9, 88.3, 290.6, 446.3, 24.2, 35.3, 388.0, 557.5, 36.…
# Allow Default X Axis Labels
ggplot(shinhancard, aes(x=일별)) +
geom_line(aes(y=`카드이용건수(천건)`)) +
labs(title="Time Series Chart",
subtitle="Returns Percentage from 'Economics' Dataset",
caption="Source: Economics",
y="Returns %")
- 이상하다, 분명 시각화를 진행했는데, 검은색의 데이터가 존재한다.
- 왜 그럴까?
shinhancard %>%
filter(일별 == "2019-01-01") %>%
dim()
## [1] 355 5
shinhancard %>%
rename(date = "일별") %>%
group_by(date) %>%
summarise(mean = mean(`카드이용건수(천건)`)) %>%
ggplot(aes(x=date)) +
geom_line(aes(y=mean)) +
theme(axis.text.x = element_text(angle=65, vjust=0.6)) +
labs(title="Time Series Chart",
subtitle="Avg. Sales from 'Shinhan Card' Dataset",
caption="Source: Shinhan Card",
y="Avg. Sales (1000)") +
theme_bw()
- 이번에는 그룹별로 시각화를 구현한다.
shinhancard %>%
rename(date = "일별", gender = "성별") %>%
group_by(date, gender) %>%
summarise(mean = mean(`카드이용건수(천건)`)) %>%
ggplot(aes(x=date)) +
geom_line(aes(y=mean, colour = gender)) +
labs(title="Time Series Chart",
subtitle="Avg. Sales from 'Shinhan Card' Dataset",
caption="Source: Shinhan Card",
y="Avg. Sales (1000)")
- 이번에는 연령대별로 소비패턴을 확인해보자.
shinhancard %>%
rename(date = "일별") %>%
group_by(date, 연령대별) %>%
summarise(mean = mean(`카드이용건수(천건)`)) %>%
ggplot(aes(x=date)) +
geom_line(aes(y=mean, colour = 연령대별)) +
labs(title="Time Series Chart",
subtitle="Avg. Sales from 'Shinhan Card' Dataset",
caption="Source: Shinhan Card",
y="Avg. Sales (1000)")
- 위와 같이 그래프를 확장하면서 계속 그릴 수가 있다.
- 성별로 구분해서 보는 것도 도움이 되기 때문에, 이 부분은 수강생들에게 맡기도록 한다.