[R] 14. 피벗팅(pivotting)

반응형

피벗팅

  • 과거 포스팅에서 spread()와 gather() 함수에 대해서 설명드린적이 있습니다.
  • 데이터를 long format 또는 wide format으로 변환시키는 방법에 대한 설명입니다.
  • 이번에는 같은 내용이지만 tidyverse 라이브러리에 있는 다른 함수를 사용하는 방법에 대해서 말씀드리겠습니다.
    • 물론 spread(), gather() 함수 역시 같이 구동되는 tidyr 라이브러리의 내장 함수입니다만,
      사용성을 더 개선한 함수가 있습니다.



예시로 쓰일 데이터 예제

set.seed(2021)

# 임의로 데이터를 생성한다. (100명의 유저가 특정 곡을 스트리밍한 이력)
temp <- tibble(
  user_id = c(10000:10099),
  user_age = sample(x = round(runif(n = 100, min = 18, max = 50), 0), size = 100, replace = TRUE),
  user_gender = sample(x = c("남성", "여성"), size = 100, replace = TRUE),
  song_id = sample(x = letters[1:15], size = 100, replace = TRUE),
  streaming_count = rpois(n = 100, lambda = 20)
) %>% 
  mutate(
    song_class_flag = case_when(
      song_id %in% c("d", "e", "f") ~ "인기곡",
      TRUE ~ "비인기곡"
    )
  )

temp
## # A tibble: 100 x 6
##    user_id user_age user_gender song_id streaming_count song_class_flag
##      <int>    <dbl> <chr>       <chr>             <int> <chr>          
##  1   10000       49 여성        i                    19 비인기곡       
##  2   10001       49 여성        m                    28 비인기곡       
##  3   10002       26 여성        f                    21 인기곡         
##  4   10003       48 남성        e                    14 인기곡         
##  5   10004       49 여성        o                    17 비인기곡       
##  6   10005       37 여성        h                    22 비인기곡       
##  7   10006       48 여성        n                    15 비인기곡       
##  8   10007       43 남성        g                    22 비인기곡       
##  9   10008       22 남성        m                    28 비인기곡       
## 10   10009       34 여성        g                    18 비인기곡       
## # … with 90 more rows



pivot_wider()

  • spread() 함수와 유사합니다.
  • argument는 names_fromvalues_from 이라는 파라미터를 받아 사용합니다.
  • 과거에 설명했던 포스팅을 읽고 오시면 도움이 많이 됩니다!
  • 바로 예시로 설명드리겠습니다. 먼저 아래와 같이 성별(user_gender), 곡(song_id)별 스트리밍 횟수 합산이 아래와 같이 있다고 가정합니다.
temp2 <- temp %>% 
  group_by(user_gender, song_id) %>% 
  summarise(total_streaming_count = sum(streaming_count)) %>% 
  ungroup()
## `summarise()` has grouped output by 'user_gender'. You can override using the `.groups` argument.
temp2
## # A tibble: 30 x 3
##    user_gender song_id total_streaming_count
##    <chr>       <chr>                   <int>
##  1 남성        a                          43
##  2 남성        b                         127
##  3 남성        c                          33
##  4 남성        d                          65
##  5 남성        e                          44
##  6 남성        f                          98
##  7 남성        g                         146
##  8 남성        h                          50
##  9 남성        i                          48
## 10 남성        j                          45
## # … with 20 more rows
  • 이 것을 song_id 기준으로 wide format 형태로 피벗팅하기 위해선 아래와 같이 작성합니다.
temp2_wider <- temp2 %>% 
  pivot_wider(
    names_from = "song_id",
    values_from = "total_streaming_count"
  )

temp2_wider
## # A tibble: 2 x 16
##   user_gender     a     b     c     d     e     f     g     h     i     j     k
##   <chr>       <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 남성           43   127    33    65    44    98   146    50    48    45    24
## 2 여성          104    21    37    35    74    63   100    69    19    82    42
## # … with 4 more variables: l <int>, m <int>, n <int>, o <int>
  • 즉, 기존의 spread() 함수에서 keynames_from, valuevalues_from으로 바뀌었다고 보시면 이해가 훨씬 더 편합니다.

 

  • 위 결과를 pivot_longer() 함수를 써서 다시 long format으로 피벗팅해보겠습니다.
temp2_longer <- temp2_wider %>% 
  pivot_longer(
    cols = 2:16,
    names_to = "song_id",
    values_to = "total_streaming_count"
  )

temp2_longer
## # A tibble: 30 x 3
##    user_gender song_id total_streaming_count
##    <chr>       <chr>                   <int>
##  1 남성        a                          43
##  2 남성        b                         127
##  3 남성        c                          33
##  4 남성        d                          65
##  5 남성        e                          44
##  6 남성        f                          98
##  7 남성        g                         146
##  8 남성        h                          50
##  9 남성        i                          48
## 10 남성        j                          45
## # … with 20 more rows
  • wide format에서 long format으로 변형하고 싶은 변수의 위치를 cols argument에 적고,
    새롭게 나올 변수의 이름을 names_to, 변수에 들어갈 값을 value_to로 정의하시면 됩니다.

 

  • 저는 개인적으로 spread(), gather()를 많이써왔기에 이게 조금 더 익숙하긴 하지만..
    함수의 이름이나 argument는 pivot_wider(), pivot_longer()가 조금 더 직관적이지 않나.. 생각이 듭니다.
반응형
TAGS.

Comments