Потеря повторяющихся имен столбцов при сведении списков списков в кадры данных в R - PullRequest
0 голосов
/ 25 апреля 2020

Этот тип вопроса о «сведении списков в рамки данных» задавался несколько раз, однако я не смог найти решение, которое помогло бы решить мою конкретную проблему. Я сделал небольшой пример ниже. В общем, при использовании httr в R для получения данных из API, большинство API данных, которые я использовал для извлечения данных, возвращают данные в аналогичном формате вложенных списков списков, который выглядит примерно так:

nested_list = list(
  list(
    name = 'joe', 
    match = 13, 
    team = list(
      list(
        name = 'teama'          
      ),
      list(
        name = 'teamb'
      )
    )
  ),
  list(
    name = 'tom', 
    match = 15, 
    team = list(
      list(
        name = 'teamc'          
      ),
      list(
        name = 'teamd'
      )
    )
  )
)

Я некоторое время работал над хорошей функцией, чтобы сгладить вложенные списки списков, поскольку с плоскими кадрами данных гораздо проще работать для аналитики в R. Вот мой текущий подход, сводящий к 2D :

nested_list %>%
  purrr::map(unlist) %>%
  purrr::map(t) %>%
  purrr::map(as_tibble) %>%
  dplyr::bind_rows() %>%
  readr::type_convert() # optional, to format column types

Этот подход обычно работает нормально, однако после вызова карты as_tibble, если во вложенном списке списков есть повторяющиеся ключи, они заменяются именами столбцов V1, V2 , V3, et c. Ниже показаны шаги, которые приводят к этой проблеме:

unlist

> nested_list %>% purrr::map(unlist)
[[1]]
     name     match team.name team.name 
    "joe"      "13"   "teama"   "teamb" 

[[2]]
     name     match team.name team.name 
    "tom"      "15"   "teamc"   "teamd"

unlist и транспонирование

> nested_list %>% purrr::map(unlist) %>% purrr::map(t)
[[1]]
     name  match team.name team.name
[1,] "joe" "13"  "teama"   "teamb"  

[[2]]
     name  match team.name team.name
[1,] "tom" "15"  "teamc"   "teamd"  

unlist и transpose и as_tibble

> nested_list %>% purrr::map(unlist) %>% purrr::map(t) %>% purrr::map(as_tibble)

[[1]]
# A tibble: 1 x 4
  name  match team.name V4   
  <chr> <chr> <chr>     <chr>
1 joe   13    teama     teamb

[[2]]
# A tibble: 1 x 4
  name  match team.name V4   
  <chr> <chr> <chr>     <chr>
1 tom   15    teamc     teamd

В моем полном наборе данных есть много повторяющихся имен столбцов, слишком много, чтобы кодировать ручные исправления для обновления этих имен столбцов. Скорее, было бы хорошо, если бы дублированные имена обрабатывались лучше (возможно, с team.name.1 и team.name.2).

Есть ли другой способ сгладить этот список списков для сохранения имен столбцов, например это? Любая помощь с этим будет принята с благодарностью!

1 Ответ

1 голос
/ 25 апреля 2020

as_tibble имеет параметр .name_repair. Установка в "unique" делает то, что вы хотите:

nested_list %>%
  purrr::map(unlist) %>% 
  purrr::map(t) %>% 
  purrr::map(as_tibble, .name_repair = "unique") %>% 
  dplyr::bind_rows() %>%
  readr::type_convert()


# A tibble: 2 x 4
  name  match team.name...3 team.name...4
  <chr> <dbl> <chr>         <chr>        
1 joe      13 teama         teamb        
2 tom      15 teamc         teamd   

Обратите внимание, что мы передаем эту опцию вызову purrr::map(), и она передается вызову as_tibble.

Другой совет: если вы замените свой последний purrr::map() на purrr:map_dfr(), bind_rows() будет автоматически выполнен.

...