【问题标题】:Losing duplicate column names when flattening list-of-lists into dataframes in R将列表列表展平为 R 中的数据框时丢失重复的列名
【发布时间】:2020-08-08 14:45:52
【问题描述】:

这种类型的“将列表扁平化为数据框”问题已被问过几次,但是我找不到对我的特定问题有帮助的解决方案。我在下面做了一个小例子。通常,当在 R 中使用 httr 从 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 等。我展示导致此问题的以下步骤:

取消列出

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

unlist and transpose and 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)会更好。

还有其他方法可以展平这个列表列表以保留这样的列名吗?

【问题讨论】:

    标签: r list dataframe data-manipulation


    【解决方案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() 会自动完成。

    【讨论】:

      猜你喜欢
      • 2018-11-09
      • 2020-05-31
      • 2019-03-08
      • 2021-04-02
      • 2016-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-16
      相关资源
      最近更新 更多