데이터 전처리

데이터 과학자는 사실 데이터 청소부라는 역할이 더 걸맞는 직무일지도 모른다. 왜냐하면, 대부분의 시간을 데이터 청소에 보내기 때문이다. 다음 뉴욕 타임즈(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가 필수적인 연장이 된다.

데이터 청소부 역할

데이터 청소부 1

초창기 관심을 받아 안정화 단계를 거친 것으로 평가받고 있으며 크게 데이터 정제과정에서 애로가 많은 변수명과 중복행 검출, 그리고 표 데이터 생성에 유용하다.

변수명

과거 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

중복행(row) - 중복제거

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)