데이터 과학자는 사실 데이터 청소부라는 역할이 더 걸맞는 직무일지도 모른다. 왜냐하면, 대부분의 시간을 데이터 청소에 보내기 때문이다. 다음 뉴욕 타임즈(2014) 기사에 어떻게 보면 데이터과학 본질이 잘 나타나 있다.
Data scientists, according to interviews and expert estimates, spend from 50 percent to 80 percent of their time mired in this more mundane labor of collecting and preparing unruly digital data, before it can be explored for useful nuggets.
– “For Big-Data Scientists, ‘Janitor Work’ Is Key Hurdle to Insight” - The New York Times, 2014
원본데이터를 readr
팩키지 다양한 함수로 가져오면 가장 먼저하는 역할이 데이터를 길들이는 것이다. 모형과 시각화를 위해서 데이터 사각형화(data rectangling) 이전에 데이터 전처리가 수반되고, 데이터 전처리는 데이터 정제작업(cleaning)과 함께 데이터 길들이기(taming)를 포함한다.
이를 위해서 청소부(janitor) 팩키지와 skimr
이 동원되고, tidyr
, dplyr
가 필수적인 연장이 된다.
초창기 관심을 받아 안정화 단계를 거친 것으로 평가받고 있으며 크게 데이터 정제과정에서 애로가 많은 변수명과 중복행 검출, 그리고 표 데이터 생성에 유용하다.
과거 make.names()
함수로 난잡한 변수명 문제를 처리했다면, 이제 clean_names()
함수로 변수명 문제를 깔끔하게 정리할 수 있다.
난감한 상황
# 0. 환경설정 -----
library(janitor)
library(tidyverse)
# browseVignettes(package="janitor")
# 1. 변수명 -----
test_df <- as.data.frame(matrix(ncol = 6))
names(test_df) <- c("hIgHlo", "REPEAT VALUE", "REPEAT VALUE", "% successful (2009)", "abc@!*", "")
test_df
hIgHlo REPEAT VALUE REPEAT VALUE % successful (2009) abc@!*
1 NA NA NA NA NA NA
청수부 동원
# make.names
test_df %>%
clean_names()
h_ig_hlo repeat_value repeat_value_2 percent_successful_2009 abc x
1 NA NA NA NA NA NA
get_dedups()
함수로 중복되는 행을 빠를게 찾아내서 검출할 수 있다.
# 2. 중복행(row): dedup rows -----
mtcars %>%
get_dupes(wt, cyl)
# A tibble: 4 x 12
wt cyl dupe_count mpg disp hp drat qsec vs am gear
<dbl> <dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 3.44 6 2 19.2 168. 123 3.92 18.3 1 0 4
2 3.44 6 2 17.8 168. 123 3.92 18.9 1 0 4
3 3.57 8 2 14.3 360 245 3.21 15.8 0 0 3
4 3.57 8 2 15 301 335 3.54 14.6 0 1 5
# ... with 1 more variable: carb <dbl>
범주형 데이터를 살펴보기 위해서 표를 많이 사용한다. 하지만, table()
함수로 데이터를 살펴보면 난감하기 그지없다.
# 3. 표 데이터 -----
table(mtcars$gear, mtcars$cyl)
4 6 8
3 1 2 12
4 8 4 0
5 2 1 2
이를 타계하기 위해서 tabyl()
함수를 사용하고 다양한 꾸미기 동사를 동원해서 표를 생성시킬 수 있다. 행중심과 열중심으로 데이터프레임을 표형식 데이터프레임으로 변환시킨다.
열중심 표
mtcars %>%
tabyl(gear, cyl) %>%
adorn_totals("col") %>%
adorn_percentages("row") %>%
adorn_pct_formatting(digits = 2) %>%
adorn_ns() %>%
DT::datatable(rownames = FALSE)
행중심 표
mtcars %>%
tabyl(gear, cyl) %>%
adorn_totals("row") %>%
adorn_percentages("col") %>%
adorn_pct_formatting(digits = 2) %>%
adorn_ns() %>%
DT::datatable(rownames = FALSE)
앞서 맞보기한 tabyl()
함수를 단변량인 경우 파이프 연산자를 동원하여 빈도수와 비율을 계산한다.
## 3.1. 단변량 표 -----
humans <- starwars %>%
filter(species == "Human")
humans %>%
tabyl(eye_color) %>%
adorn_totals("row") %>%
adorn_pct_formatting() %>%
arrange(desc(n))
eye_color n percent
1 Total 35 100.0%
2 brown 17 48.6%
3 blue 12 34.3%
4 hazel 2 5.7%
5 yellow 2 5.7%
6 blue-gray 1 2.9%
7 dark 1 2.9%
이변량인 경우도 앞서와 같은 방식으로 표작성도 가능하고 knitr
팩키지 kable()
함수로 바로 뽑아 꾸미는 것도 가능하다.
## 3.2. 두변량 표 -----
humans %>%
tabyl(eye_color, gender) %>%
adorn_percentages("row") %>%
adorn_pct_formatting(rounding = "half up", digits = 0) %>%
adorn_ns() %>%
adorn_title("combined", row_name = "눈색상", col_name = "성별") %>%
knitr::kable()
눈색상/성별 | female | male |
---|---|---|
blue | 25% (3) | 75% (9) |
blue-gray | 0% (0) | 100% (1) |
brown | 29% (5) | 71% (12) |
dark | 0% (0) | 100% (1) |
hazel | 50% (1) | 50% (1) |
yellow | 0% (0) | 100% (2) |