назовите элементы в столбце, список которых создан «гнездом» (tidyr)с помощью пользовательской функции

#r #dplyr #tidyverse #tidyr #purrr

Вопрос:

У меня есть tibble , который я хотел бы nest() , а затем unnest_wider() , сохраняя при этом копию вложенных данных в формате tibble. Я знаю, что это звучит не очень элегантно, но на данный момент это лучшее решение для моего варианта использования. однако, когда я использую unnest_wider() функцию, name_repair создает уродливые ...1 ...2 имена и т. Д. Как я могу назвать элементы в списке (они разной длины) с помощью некоторой purrr функции (https://community.rstudio.com/t/how-to-handle-lack-of-names-with-unnest-wider/40496)? так что, когда я unnest_wider() буду, у столбцов будут более приятные имена.

небольшой пример того, что я ищу:

 library(tidyverse)
mpg %>%
  select(manufacturer, model, cty   ) %>%
  group_by(manufacturer, model) %>%
  nest() %>%
  mutate(vars_in_tibble = data) %>%
  ungroup() %>%
  unnest_wider(data) %>%
  unnest_wider(cty)
 

дает

 # A tibble: 38 x 14
   manufacturer model               ...1  ...2  ...3  ...4  ...5  ...6  ...7  ...8  ...9 ...10 ...11 vars_in_tibble       
   <chr>        <chr>              <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <list>               
 1 audi         a4                    18    21    20    21    16    18    18    NA    NA    NA    NA <tibble[,1] [7 x 1]> 
 2 audi         a4 quattro            18    16    20    19    15    17    17    15    NA    NA    NA <tibble[,1] [8 x 1]> 
 3 audi         a6 quattro            15    17    16    NA    NA    NA    NA    NA    NA    NA    NA <tibble[,1] [3 x 1]> 
 4 chevrolet    c1500 suburban 2wd    14    11    14    13    12    NA    NA    NA    NA    NA    NA <tibble[,1] [5 x 1]> 
 5 chevrolet    corvette              16    15    16    15    15    NA    NA    NA    NA    NA    NA <tibble[,1] [5 x 1]> 
 6 chevrolet    k1500 tahoe 4wd       14    11    11    14    NA    NA    NA    NA    NA    NA    NA <tibble[,1] [4 x 1]> 
 7 chevrolet    malibu                19    22    18    18    17    NA    NA    NA    NA    NA    NA <tibble[,1] [5 x 1]> 
 8 dodge        caravan 2wd           18    17    16    16    17    17    11    15    15    16    16 <tibble[,1] [11 x 1]>
 9 dodge        dakota pickup 4wd     15    14    13    14    14    14     9    11    11    NA    NA <tibble[,1] [9 x 1]> 
10 dodge        durango 4wd           13    13     9    13    11    13    11    NA    NA    NA    NA <tibble[,1] [7 x 1]> 
 

но я хочу

 # A tibble: 38 x 14
   manufacturer model              car_1 car_2 car_3 car_4 car_5 car_6 car_7 car_8 car_9 car_10 car_11 vars_in_tibble       
   <chr>        <chr>              <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <list>               
 1 audi         a4                    18    21    20    21    16    18    18    NA    NA    NA    NA <tibble[,1] [7 x 1]> 
 2 audi         a4 quattro            18    16    20    19    15    17    17    15    NA    NA    NA <tibble[,1] [8 x 1]> 
 3 audi         a6 quattro            15    17    16    NA    NA    NA    NA    NA    NA    NA    NA <tibble[,1] [3 x 1]> 
 4 chevrolet    c1500 suburban 2wd    14    11    14    13    12    NA    NA    NA    NA    NA    NA <tibble[,1] [5 x 1]> 
 5 chevrolet    corvette              16    15    16    15    15    NA    NA    NA    NA    NA    NA <tibble[,1] [5 x 1]> 
 6 chevrolet    k1500 tahoe 4wd       14    11    11    14    NA    NA    NA    NA    NA    NA    NA <tibble[,1] [4 x 1]> 
 7 chevrolet    malibu                19    22    18    18    17    NA    NA    NA    NA    NA    NA <tibble[,1] [5 x 1]> 
 8 dodge        caravan 2wd           18    17    16    16    17    17    11    15    15    16    16 <tibble[,1] [11 x 1]>
 9 dodge        dakota pickup 4wd     15    14    13    14    14    14     9    11    11    NA    NA <tibble[,1] [9 x 1]> 
10 dodge        durango 4wd           13    13     9    13    11    13    11    NA    NA    NA    NA <tibble[,1] [7 x 1]> 

 

Ответ №1:

Вы можете преобразовать вложенный список в именованный список с помощью purrr::карта, подобная этой

 mpg %>%
  select(manufacturer, model, cty) %>%
  group_by(manufacturer, model) %>%
  nest() %>%
  mutate(vars_in_tibble = data,
         data = map(data, ~.x %>% mutate(id = paste0('cty_', row_number())) %>%
                      pivot_wider(names_from = id, values_from = cty)
                    )) %>%
  ungroup() %>%
  unnest(data)

# A tibble: 38 x 14
   manufacturer model              cty_1 cty_2 cty_3 cty_4 cty_5 cty_6 cty_7 cty_8 cty_9 cty_10 cty_11 vars_in_tibble      
   <chr>        <chr>              <int> <int> <int> <int> <int> <int> <int> <int> <int>  <int>  <int> <list>              
 1 audi         a4                    18    21    20    21    16    18    18    NA    NA     NA     NA <tibble[,1] [7 x 1]>
 2 audi         a4 quattro            18    16    20    19    15    17    17    15    NA     NA     NA <tibble[,1] [8 x 1]>
 3 audi         a6 quattro            15    17    16    NA    NA    NA    NA    NA    NA     NA     NA <tibble[,1] [3 x 1]>
 4 chevrolet    c1500 suburban 2wd    14    11    14    13    12    NA    NA    NA    NA     NA     NA <tibble[,1] [5 x 1]>
 5 chevrolet    corvette              16    15    16    15    15    NA    NA    NA    NA     NA     NA <tibble[,1] [5 x 1]>
 6 chevrolet    k1500 tahoe 4wd       14    11    11    14    NA    NA    NA    NA    NA     NA     NA <tibble[,1] [4 x 1]>
 7 chevrolet    malibu                19    22    18    18    17    NA    NA    NA    NA     NA     NA <tibble[,1] [5 x 1]>
 8 dodge        caravan 2wd           18    17    16    16    17    17    11    15    15     16     16 <tibble[,1] [11 x 1~
 9 dodge        dakota pickup 4wd     15    14    13    14    14    14     9    11    11     NA     NA <tibble[,1] [9 x 1]>
10 dodge        durango 4wd           13    13     9    13    11    13    11    NA    NA     NA     NA <tibble[,1] [7 x 1]>
# ... with 28 more rows
 

Комментарии:

1. Это, безусловно, самое чистое решение на данный момент и ответ, наиболее близкий к исходному вопросу.

Ответ №2:

Тот же результат другой подход —

 library(dplyr)
library(tidyr)

mpg %>%
  select(manufacturer, model, cty) %>%
  group_by(manufacturer, model) %>%
  mutate(col = paste0('cty', row_number())) %>%
  ungroup %>%
  pivot_wider(names_from = col, values_from  = cty) %>%
  rowwise() %>%
  mutate(vars_in_tibble = list(tibble(cty = na.omit(c_across(starts_with('cty')))))) %>%
  ungroup

#   manufacturer model             cty1  cty2  cty3  cty4  cty5  cty6  cty7  cty8  cty9 cty10 cty11 vars_in_tibble  
#   <chr>        <chr>            <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <list>          
# 1 audi         a4                  18    21    20    21    16    18    18    NA    NA    NA    NA <tibble [7 × 1]>
# 2 audi         a4 quattro          18    16    20    19    15    17    17    15    NA    NA    NA <tibble [8 × 1]>
# 3 audi         a6 quattro          15    17    16    NA    NA    NA    NA    NA    NA    NA    NA <tibble [3 × 1]>
# 4 chevrolet    c1500 suburban …    14    11    14    13    12    NA    NA    NA    NA    NA    NA <tibble [5 × 1]>
# 5 chevrolet    corvette            16    15    16    15    15    NA    NA    NA    NA    NA    NA <tibble [5 × 1]>
# 6 chevrolet    k1500 tahoe 4wd     14    11    11    14    NA    NA    NA    NA    NA    NA    NA <tibble [4 × 1]>
# 7 chevrolet    malibu              19    22    18    18    17    NA    NA    NA    NA    NA    NA <tibble [5 × 1]>
# 8 dodge        caravan 2wd         18    17    16    16    17    17    11    15    15    16    16 <tibble [11 × 1…
# 9 dodge        dakota pickup 4…    15    14    13    14    14    14     9    11    11    NA    NA <tibble [9 × 1]>
#10 dodge        durango 4wd         13    13     9    13    11    13    11    NA    NA    NA    NA <tibble [7 × 1]>
# … with 28 more rows
 

Ответ №3:

Я думаю, вы можете добавить последнюю строку в свой код:

 library(stringr)

mpg %>%
  select(manufacturer, model, cty   ) %>%
  group_by(manufacturer, model) %>%
  nest() %>%
  mutate(vars_in_tibble = data) %>%
  ungroup() %>%
  unnest_wider(data) %>%
  unnest_wider(cty) %>%
  rename_with(~ str_replace(., "\.\.\.", "car_"), contains("..."))


# A tibble: 38 x 14
   manufacturer model         car_1 car_2 car_3 car_4 car_5 car_6 car_7 car_8 car_9 car_10 car_11
   <chr>        <chr>         <int> <int> <int> <int> <int> <int> <int> <int> <int>  <int>  <int>
 1 audi         a4               18    21    20    21    16    18    18    NA    NA     NA     NA
 2 audi         a4 quattro       18    16    20    19    15    17    17    15    NA     NA     NA
 3 audi         a6 quattro       15    17    16    NA    NA    NA    NA    NA    NA     NA     NA
 4 chevrolet    c1500 suburb~    14    11    14    13    12    NA    NA    NA    NA     NA     NA
 5 chevrolet    corvette         16    15    16    15    15    NA    NA    NA    NA     NA     NA
 6 chevrolet    k1500 tahoe ~    14    11    11    14    NA    NA    NA    NA    NA     NA     NA
 7 chevrolet    malibu           19    22    18    18    17    NA    NA    NA    NA     NA     NA
 8 dodge        caravan 2wd      18    17    16    16    17    17    11    15    15     16     16
 9 dodge        dakota picku~    15    14    13    14    14    14     9    11    11     NA     NA
10 dodge        durango 4wd      13    13     9    13    11    13    11    NA    NA     NA     NA
# ... with 28 more rows, and 1 more variable: vars_in_tibble <list>