在R中,将列表扁平化为数据框时,会丢失重复的列名。

问题描述 投票:0回答:1

这种类型的 "将列表扁平化为数据框 "的问题已经被问过几次了,然而我找不到对我的特殊问题有帮助的解决方案。我在下面做了一个小例子。一般来说,当使用 httr 在R中从apis中获取数据,我用过的大多数数据apis都以类似嵌套列表的格式返回数据,看起来是这样的。

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 map被调用,如果嵌套的list-of-list中有重复的键,那么就会用列名V1、V2、V3等代替。我在下面展示了导致这个问题的步骤。

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"

拆单

> 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"  

解列和转置以及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.1team.name.2).

有没有其他方法可以将这个list-of-list扁平化,保留这样的列名?如果有任何帮助,我将非常感激!

r list dataframe data-manipulation
1个回答
1
投票

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() 是自动完成的。

© www.soinside.com 2019 - 2024. All rights reserved.