【问题标题】:Split a list into separate data frame in R将列表拆分为R中的单独数据框
【发布时间】:2020-03-28 21:05:26
【问题描述】:

所以我有一个如下列表,我想要将它们分成三个单独的数据框(名称为香蕉/草莓和苹果),如预期输出所示。我已经看到了这个(Splitting List into dataframe R),但这与我想要的完全相反。我不想合并,然后我想将它们拆分为三个与列表标题同名的数据框。

list_a <- list(`Banana` = c(8.7), `Strawberry` = c(2.3), `Apple` = c(3.5))

DF1

Banana
8.7

DF2

Strawberry
2.3

DF3

Apple
3.5

任何最好在 Tidyverse 中的解决方案都将不胜感激。实际问题在列表中有更多列。

【问题讨论】:

    标签: r dplyr tidyverse purrr


    【解决方案1】:

    我们可以使用imap获取名称,然后使用set_names

    library(purrr)
    library(dplyr)
    library(stringr)
    imap(list_a, ~ set_names(tibble(.x), .y)) %>%
            set_names(str_c("DF", 1:3)) %>% 
            list2env(.GlobalEnv)
    
    DF1
    # A tibble: 1 x 1
    #  Banana
    #   <dbl>
    #1    8.7
    DF2
    # A tibble: 1 x 1
    #  Strawberry
    #       <dbl>
    #1        2.3
    DF3
    # A tibble: 1 x 1
    #  Apple
    #  <dbl>
    #1   3.5
    

    如果我们需要单独的列

    library(tibble)
    enframe(list_a) %>% 
         unnest(c(value)) %>% 
         group_split(rn = row_number(), keep = FALSE) %>%
         set_names(str_c("DF", 1:3)) %>% 
         list2env(.GlobalEnv)
    DF1
    # A tibble: 1 x 2
    #  name   value
    #  <chr>  <dbl>
    #1 Banana   8.7
    DF2
    # A tibble: 1 x 2
    #  name       value
    #  <chr>      <dbl>
    #1 Strawberry   2.3
    DF3
    # A tibble: 1 x 2
    #  name  value
    #  <chr> <dbl>
    #1 Apple   3.5
    

    【讨论】:

    • Akrun,如果我们必须在每个数据帧中获得一个单独的列来说明数据帧的名称,也可以这样做。例如:Banana df 标头看起来像 Type & value,第一行是 Banana & 8.7
    【解决方案2】:

    没有以前的答案那么简单,但您可以使用 for 循环获得它:

    for(i in 1:length(list_a))
    {
      df <- data.frame(unlist(list_a[[i]]))
      colnames(df) <- names(list_a[i])
      assign(names(list_a[i]),df, .GlobalEnv)
    }  
    

    【讨论】:

      【解决方案3】:

      首先将它们全部转换为 tibble:

      list_a <- list(`Banana` = c(8.7), `Strawberry` = c(2.3), `Apple` = c(3.5))
      list_a <- purrr::map(list_a, tibble::as_tibble)
      

      然后将此发送到全局环境:

      list2env(list_a, envir = .GlobalEnv)
      

      【讨论】:

      • 这太棒了,谢谢。我只有一个问题,我认为它的出现是因为我的列表标题实际上是 [[1]]、[[2]] 和 [[3]]。所以我在最后一行运行你的代码时,它给了我下面的错误任何帮助?list2env(., envir = .GlobalEnv) 中的错误:names(x) must be a character vector of the same length as x
      • Ronak 的回答解决了我上面提到的这个问题
      • 是的,如果您的数据没有命名列表,则需要按照其他答案中的方式设置名称。
      【解决方案4】:

      tidyverse 的方式是

      library(tidyverse)
      
      new_list <- set_names(map2(list_a,names(list_a),  
                          ~tibble(!!.y := .x)), str_c("df", 1:3))
      

      它也可以在基础 R 中完成

      new_list <- setNames(Map(function(x, y) setNames(data.frame(x), y), 
                          list_a,names(list_a)), paste0("df", 1:3))
      

      现在我们可以将它写入全局环境。

      list2env(new_list, .GlobalEnv)
      

      【讨论】:

      • 这简直是天才。我是你罗纳克的粉丝。它也处理了命名列表。聪明的 !我在下面遇到的一个问题。 IDK,如果这是一个愚蠢的问题,但真的很感谢及时回复:)
      • @VaibhavSingh 是的,要使用list2env,您需要一个命名列表。来自?list2envx - a list, where names(x) must not contain empty ("") elements.。所以你需要在使用它之前给列表命名。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      • 2019-04-03
      • 2021-10-11
      • 2015-01-15
      相关资源
      最近更新 更多