7장 tibble로하는티블

7.1 들어가기

  • 현재 전통적인 ‘data.frame’ 대신 ‘tibble’을 가지고 작업 한다.
  • 티블도 ‘data.frame’이지만, 편리하게 사용 할 수 있도록 오래된 동작을 수정한 것 이다.
  • R은 오래된 언어로 기존의 유용했던 동작들이 그렇지 않을 수 있다.
  • 기존 코드를 손상시키지 않으면서 베이스 R을 변경하기가 어렵기 때문에 대부분의 혁신은 패키지로 나타난다.
  • Tibble 패키지에 대해서 설명할 것인데, 이는 tidyverse의 작업을 약간 쉽게 만들어주는 데이터프레임을 제공한다.

7.1.1 준비하기

  • Tidyverse 패키지의 핵심 중 하나인 tibble 패키지 살펴보기
library(tidyverse)

7.2 티블생성하기

  • 대부분의 함수는 tidyverse의 통합 특성 중 하나인 티블을 생성한다.
  • 대부분의 R패키지는 일반적인 데이터프레임을 사용하므로, 데이터프레임을 티블로 강제 변경해야 할 경우가 있다.
as_tibble(iris)
## # A tibble: 150 x 5
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
##           <dbl>       <dbl>        <dbl>       <dbl> <fct>  
##  1          5.1         3.5          1.4         0.2 setosa 
##  2          4.9         3            1.4         0.2 setosa 
##  3          4.7         3.2          1.3         0.2 setosa 
##  4          4.6         3.1          1.5         0.2 setosa 
##  5          5           3.6          1.4         0.2 setosa 
##  6          5.4         3.9          1.7         0.4 setosa 
##  7          4.6         3.4          1.4         0.3 setosa 
##  8          5           3.4          1.5         0.2 setosa 
##  9          4.4         2.9          1.4         0.2 setosa 
## 10          4.9         3.1          1.5         0.1 setosa 
## # ... with 140 more rows
  • tibble()을 사용하여 개별 벡터로부터 새로운 티블을 만들 수 있다.
  • tibble()은 길이가 1인 입력을 자동으로 재사용하며, 아래에 보이는 것 같이 방금 만든 변수를 참조할 수 있다.
tibble(
x = 1:5,
y = 1,
z = x ^ 2 + y
)
## # A tibble: 5 x 3
##       x     y     z
##   <int> <dbl> <dbl>
## 1     1     1     2
## 2     2     1     5
## 3     3     1    10
## 4     4     1    17
## 5     5     1    26
  • tibble()은 동작의 규모가 훨씬 작다는 것에 주의해야 한다.

  • 입력의 유형을 절대로 변경하지 않고, 변수의 이름을 바꾸거나 행 이름을 생성하지 않는다.

  • 티블은 R 변수명으로는 유효하지 않은 이름도 열 이름으로 가질 수 있다.

  • 문자로 시작하지 않거나 공백과 같은 비정상적인 문자가 포함될 수 있다.

  • 이 변수들을 참조하려면 역따옴표로 감싸야 한다.

tb <- tibble(
`:)` = "스마일",
` ` = "스페이스",
`2000` = "숫자"
)
tb
## # A tibble: 1 x 3
##   `:)`   ` `      `2000`
##   <chr>  <chr>    <chr> 
## 1 스마일 스페이스 숫자
  • ggplot2, dplyr, tidyr 과 같은 패키지에서 이러한 변수로 작업할 때도 역따옴표가 필요하다.

  • 티블을 만드는 또 다른 방법은 tribble()을 사용하는 것이다.

  • Tribble()은 코드로 데이터를 입력하기 위해 고안되었다.

  • 열 헤더는 공식으로 정의되고(~시작), 입력은 쉼표로 구분된다.

tribble(
~x, ~y, ~z,
 #--|--|----
"a", 2, 3.6,
"b", 1, 8.5
)
## # A tibble: 2 x 3
##   x         y     z
##   <chr> <dbl> <dbl>
## 1 a         2   3.6
## 2 b         1   8.5
  • 헤더의 위치를 명확히 하기위해 종종주석을 추가한다.

7.3 티블 vs 데이터프레임

  • 티블과 전통적 데이터프레임의 용법에 두가지 주요 차이점이 있는데, 화면 출력과 서브셋하기다.

7.3.1 화면출력

  • 티블에는 처음 10개의 행과, 화면에 들어가는 열 모두를 보여주는 정교한 화면 출력 방법이 있다.
  • 이를 이용하면 대용량 데이터 작업을 훨씬 쉽게 할 수 있다.
  • 또한 str()에서 가져온 기능으로 각 열의 유형을 열 이름과 더불어 표시한다.
tibble(
a = lubridate::now() + runif(1e3) * 86400,
b = lubridate::today() + runif(1e3) *30,
c = 1:1e3,
d = runif(1e3),
e = sample(letters, 1e3, replace = TRUE)
)
## # A tibble: 1,000 x 5
##    a                   b              c      d e    
##    <dttm>              <date>     <int>  <dbl> <chr>
##  1 2020-10-06 19:29:51 2020-10-20     1 0.0654 u    
##  2 2020-10-06 19:22:04 2020-10-24     2 0.0323 q    
##  3 2020-10-07 06:04:40 2020-10-15     3 0.885  i    
##  4 2020-10-07 09:52:26 2020-10-14     4 0.180  m    
##  5 2020-10-07 06:40:49 2020-11-03     5 0.214  l    
##  6 2020-10-07 06:42:19 2020-10-17     6 0.455  x    
##  7 2020-10-06 20:06:25 2020-10-08     7 0.164  d    
##  8 2020-10-07 12:53:20 2020-10-08     8 0.485  m    
##  9 2020-10-07 06:14:21 2020-10-29     9 0.937  l    
## 10 2020-10-06 22:14:02 2020-10-09    10 0.677  n    
## # ... with 990 more rows
  • 티블은 큰 데이터프레임을 화면 출력할 때 실수로 콘솔을 넘어가지 않도록 설계 되었다.
  • 그러나 때로는 기본 디스플레이보다 더 많은 출력이 필요하곤 하다. 도움이 될 수 있는 몇 가지 옵션이 있다.
  • 먼저 데이터프레임을 명시적으로 print()로 화면 출력하고 디스플레이의 행수(n)와 너비(w)를 제어할 수 있다, width = Inf를 하면 모든 열을 표시한다.
nycflights13::flights %>%
print(n = 10, width = Inf)
## # A tibble: 336,776 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
##    arr_delay carrier flight tailnum origin dest  air_time distance  hour minute
##        <dbl> <chr>    <int> <chr>   <chr>  <chr>    <dbl>    <dbl> <dbl>  <dbl>
##  1        11 UA        1545 N14228  EWR    IAH        227     1400     5     15
##  2        20 UA        1714 N24211  LGA    IAH        227     1416     5     29
##  3        33 AA        1141 N619AA  JFK    MIA        160     1089     5     40
##  4       -18 B6         725 N804JB  JFK    BQN        183     1576     5     45
##  5       -25 DL         461 N668DN  LGA    ATL        116      762     6      0
##  6        12 UA        1696 N39463  EWR    ORD        150      719     5     58
##  7        19 B6         507 N516JB  EWR    FLL        158     1065     6      0
##  8       -14 EV        5708 N829AS  LGA    IAD         53      229     6      0
##  9        -8 B6          79 N593JB  JFK    MCO        140      944     6      0
## 10         8 AA         301 N3ALAA  LGA    ORD        138      733     6      0
##    time_hour          
##    <dttm>             
##  1 2013-01-01 05:00:00
##  2 2013-01-01 05:00:00
##  3 2013-01-01 05:00:00
##  4 2013-01-01 05:00:00
##  5 2013-01-01 06:00:00
##  6 2013-01-01 05:00:00
##  7 2013-01-01 06:00:00
##  8 2013-01-01 06:00:00
##  9 2013-01-01 06:00:00
## 10 2013-01-01 06:00:00
## # ... with 336,766 more rows
  • options(tibble.print_max = n, tibble.print_min = m): m행 이상인 경우, n행만 출력한다. 모든 행을 항상 표시하려면 option(dplyr.print_min = Inf)을 사용

  • Option(tibble.width = Inf): 화면 너비와 상관없이 항상 모든 열을 출력한다.

  • package?tibble패키지 도움말을 찾아보면 옵션의 전체 목록을 볼 수 있다.

  • 마지막 방법은 전체 데이터셋을 스크롤하여 볼 수 있도록 RStudio의 내장 데이터 뷰어를 사용하는 것이다. 긴 데이터 연쇄 작업의 마지막에도 이 방법은 유용하다.

nycflights13::flights %>%
view()

7.3.2 서브셋하기

  • 변수 하나를 추출하려면 새로운 도구인 $ 및 [[아 팔요하다. [[는 이름이나 위치로 추출할 수 있다.
df <- tibble(
x = runif(5),
y = rnorm(5)
)

#이름으로추출

df$x
## [1] 0.7063033 0.8754381 0.4990366 0.9936386 0.3491632
df[["x"]]
## [1] 0.7063033 0.8754381 0.4990366 0.9936386 0.3491632

#위치로추출

df[[1]]
## [1] 0.7063033 0.8754381 0.4990366 0.9936386 0.3491632
  • 파이프에서 이것들을 사용하려면 특별한 플레이스홀더인 .을 사용해야 한다.
df %>% .$x
## [1] 0.7063033 0.8754381 0.4990366 0.9936386 0.3491632
df %>% .[["x"]]
## [1] 0.7063033 0.8754381 0.4990366 0.9936386 0.3491632
  • 티블은 데이터프레임보다 좀 더 엄격하다. 절대로 부분 매칭을 사용하지 않으며, 접근하려는 열이 존재하지 않는 경우에는 경고를 생성한다.

7.4 이전 코드와 상호작용

  • 일부 오래된 함수는 티블에서 동작하지 않는다. 이러한 함수를 사용하려면 as.data.frame()을 사용하여 티블을 data.frame으로 되돌려야 한다.

class(as.data.frame(tb))

#> [1] “data.frame”

  • 오래된 함수 중 일부가 티블에서 작동하지 않는 주된 이유는 [함수 때문이다.
  • Dplyr::filter()와 dplyr::select()가 같은 문제를 더 명확한 코드로 해결할 수 있기 때문이다
  • 베이스 R의 데이터프레임을 사용하면 [는 어떨 때는 데이터프레임을 반환하고, 또 어떨 때는 벡터를 반환한다. 티블에서 [는 항상 다른 티블을 반환한다.

7.4.1 연습문제

1.어떤 객체가 tibble 인지 알 수 있는 방법은 무엇인가? (힌트: 일반 데이터프레임인 mtcars 를 화면출력해보라.) 출력해기, class, is_tibble()

2.data.frame 과 이에 해당하는 tibble 에서 다음 연산들을 비교하고 차이를 밝혀보라. 차이점은 무엇인가? 데이터프레임의 기본 동작이 혼란스러운 점은 무엇인가?

df <- data.frame(abc = 1, xyz = "a")
df$x
## [1] "a"
df[, "xyz"]
## [1] "a"
df[, c("abc", "xyz")]
##   abc xyz
## 1   1   a

3.객체에 변수 이름을 저장하고 있는 경우 (예: var <- “mpg” ), tibble 에서 이 참조 변수를 어떻게 추출할 수 있는가?

4.다음의 데이터프레임에서 비구문론적 이름을 참조하는 방법을 연습해보라.

  1. 1이라는 이름의 변수를 추출하기.
enframe(1:3)
## # A tibble: 3 x 2
##    name value
##   <int> <int>
## 1     1     1
## 2     2     2
## 3     3     3
  1. 1 vs 2 의 산점도를 플롯팅 하기.

  2. 열 2 를 열 1 로 나누어, 3 이라는 새로운 열을 생성하기.

  3. 열의 이름을 one, two, three 로 변경하기

enframe(list(one = 1, two = 2:3, three = 4:6))
## # A tibble: 3 x 2
##   name  value    
##   <chr> <list>   
## 1 one   <dbl [1]>
## 2 two   <int [2]>
## 3 three <int [3]>
annoying <- tibble(
  `1` = 1:10,
  `2` = `1` * 2 + rnorm(length('1'))
)

5.tibble::enframe() 은 어떤 동작을 하는가? 언제 사용하겠는가? 변수추출

6.tibble 의 바닥글(footer)에 화면출력되는 열 이름의 개수를 제어하는 옵션은 무엇인가? print