1 in-memory 데이터프레임 스키마

데이터분석을 위해서 데이터프레임 자료형을 파악하는 것이 무엇보다 중요하다. 먼저, palmerpenguins 팩키지 penguins 데이터프레임을 통해 이미 메모리에 올라온 데이터프레임 자료형을 파악해보자.

library(tidyverse)
library(palmerpenguins)

map_df(palmerpenguins::penguins, class) %>% 
  pivot_longer(species:year, names_to = "var_name", values_to = "data_type")
# A tibble: 8 x 2
  var_name          data_type
  <chr>             <chr>    
1 species           factor   
2 island            factor   
3 bill_length_mm    numeric  
4 bill_depth_mm     numeric  
5 flipper_length_mm integer  
6 body_mass_g       integer  
7 sex               factor   
8 year              integer  

2 .csv 파일 → 데이터프레임

palmerpenguins 팩키지에 담긴 .csv 파일을 데이터프레임으로 불러읽어들인다. 그리고 나서 앞서 palmerpenguins::penguins 데이터프레임의 스키마를 그대로 재현한다.

먼저, 모든 칼럼을 문자형으로 불러읽어 드린 후에 변수별로 자료형을 변환시킨다. col_names = 인자를 넣어 변수명도 변경할 수 있다. 모두 소문자인 변수명을 첫 알파벳만 대문자로 변경시킨 변수명을 적용시켜본다.

penguin_colnames <- palmerpenguins::penguins %>% names %>% dput %>% str_to_title
c("species", "island", "bill_length_mm", "bill_depth_mm", "flipper_length_mm", 
"body_mass_g", "sex", "year")
penguin_raw_df <- read_csv("https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv", 
         col_types = cols(.default = col_character()),
         col_names = penguin_colnames,
         locale = locale(encoding = "UTF-8"))

map_df(penguin_raw_df, class) %>% 
  pivot_longer(Species:Year, names_to = "var_name", values_to = "data_type")
# A tibble: 8 x 2
  var_name          data_type
  <chr>             <chr>    
1 Species           character
2 Island            character
3 Bill_length_mm    character
4 Bill_depth_mm     character
5 Flipper_length_mm character
6 Body_mass_g       character
7 Sex               character
8 Year              character

mutate_at() 함수로 변수를 지정하여 범주형(as.factor) 혹은 정수형(as.integer) 으로 변환시키고 나서 나머지 모든 문자형은 mutate_if() 함수로 숫자형(as.numeric)으로 변환시킨다.

penguin_raw_df <- read_csv("https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv", 
         col_types = cols(.default = col_character()),
         locale = locale(encoding = "UTF-8"))

penguin_schema_df <- penguin_raw_df %>% 
  mutate_at(vars(species, island, sex), as.factor) %>% 
  mutate_at(vars(flipper_length_mm, body_mass_g, year), as.integer) %>% 
  mutate_if(is.character, as.numeric)

map_df(penguin_schema_df, class) %>% 
  pivot_longer(species:year, names_to = "var_name", values_to = "data_type")
# A tibble: 8 x 2
  var_name          data_type
  <chr>             <chr>    
1 species           factor   
2 island            factor   
3 bill_length_mm    numeric  
4 bill_depth_mm     numeric  
5 flipper_length_mm integer  
6 body_mass_g       integer  
7 sex               factor   
8 year              integer  

앞서 데이터 스키마를 텍스트 형태로 추출할 경우 다음과 같이 모두 문자형(c)으로 지정하여 데이터프레임으로 준비한다.

penguin_schema_df <- read_csv("https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv", 
         col_types = "cccccccc",
         locale = locale(encoding = "UTF-8"))

map_df(penguin_schema_df, class) %>% 
  pivot_longer(species:year, names_to = "var_name", values_to = "data_type")
# A tibble: 8 x 2
  var_name          data_type
  <chr>             <chr>    
1 species           character
2 island            character
3 bill_length_mm    character
4 bill_depth_mm     character
5 flipper_length_mm character
6 body_mass_g       character
7 sex               character
8 year              character

앞서 정의한 모든 변수를 문자형(c)으로 지정하는 대신 변수별로 앞서 정의된 자료형에 맞춰 스키마를 지정하여 데이터프레임을 생성시킨다.

  • c: 문자형
  • f: 범주형
  • n: 숫자형
  • i: 정수형
  • l: 논리형
  • d: 날짜형
penguin_schema_df <- read_csv("https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv", 
         col_types = "ffnniifi",
         locale = locale(encoding = "UTF-8"))

map_df(penguin_schema_df, class) %>% 
  pivot_longer(species:year, names_to = "var_name", values_to = "data_type")
# A tibble: 8 x 2
  var_name          data_type
  <chr>             <chr>    
1 species           factor   
2 island            factor   
3 bill_length_mm    numeric  
4 bill_depth_mm     numeric  
5 flipper_length_mm integer  
6 body_mass_g       integer  
7 sex               factor   
8 year              integer  
type_convert(palmerpenguins::penguins)
# A tibble: 344 x 8
   species island bill_length_mm bill_depth_mm flipper_length_… body_mass_g
   <fct>   <fct>           <dbl>         <dbl>            <int>       <int>
 1 Adelie  Torge…           39.1          18.7              181        3750
 2 Adelie  Torge…           39.5          17.4              186        3800
 3 Adelie  Torge…           40.3          18                195        3250
 4 Adelie  Torge…           NA            NA                 NA          NA
 5 Adelie  Torge…           36.7          19.3              193        3450
 6 Adelie  Torge…           39.3          20.6              190        3650
 7 Adelie  Torge…           38.9          17.8              181        3625
 8 Adelie  Torge…           39.2          19.6              195        4675
 9 Adelie  Torge…           34.1          18.1              193        3475
10 Adelie  Torge…           42            20.2              190        4250
# … with 334 more rows, and 2 more variables: sex <fct>, year <int>

2.1 스키마 추측

spec_csv() 함수로 스키마를 추축할 수 있다. 또한, 스키마를 col_types = 에 넣어 스키마를 반영할 수도 있다.

penguin_spec <- spec_csv("https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv",
                         guess_max = 100)
penguin_spec
cols(
  species = col_character(),
  island = col_character(),
  bill_length_mm = col_double(),
  bill_depth_mm = col_double(),
  flipper_length_mm = col_double(),
  body_mass_g = col_double(),
  sex = col_character(),
  year = col_double()
)
penguin_spec_df <- read_csv("https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv", 
         col_types = penguin_spec,
         locale = locale(encoding = "UTF-8"))
 
# type_convert(penguin_spec_df)
 

데이터 과학자 이광춘 저작

kwangchun.lee.7@gmail.com