【问题标题】:Convert a list to a data frame将列表转换为数据框
【发布时间】:2011-05-12 18:00:45
【问题描述】:

我有一个嵌套的数据列表。它的长度是132,每一项是一个长度为20的列表。有没有快速的方法可以把这个结构转换成132行20列数据的数据框?

以下是一些可以使用的示例数据:

l <- replicate(
  132,
  as.list(sample(letters, 20)),
  simplify = FALSE
)

【问题讨论】:

  • 所以您希望每个列表元素作为 data.frame 中的一行数据?
  • @RichieCotton 这不是正确的例子。 “每个项目都是一个长度为 20 的 list”并且你得到的每个项目都是一个长度为 20 的 vector 元素列表。
  • 聚会迟到了,但我没有看到有人提到this,我认为这很方便(对于我想做的事情)。

标签: r list dataframe


【解决方案1】:

如果您的列表有相同尺寸的元素,您可以使用 tidyverse 中的 bind_rows 函数。

# Load the tidyverse
Library(tidyverse)

# make a list with elements having same dimensions
My_list <- list(a = c(1, 4, 5), b = c(9, 3, 8))

## Bind the rows
My_list %>% bind_rows()

结果是一个有两行的数据框。

【讨论】:

    【解决方案2】:

    以下简单的命令对我有用:

    myDf <- as.data.frame(myList)
    

    参考 (Quora answer)

    > myList <- list(a = c(1, 2, 3), b = c(4, 5, 6))
    > myList
    $a
    [1] 1 2 3
     
    $b
    [1] 4 5 6
     
    > myDf <- as.data.frame(myList)
      a b
    1 1 4
    2 2 5
    3 3 6
    > class(myDf)
    [1] "data.frame"
    

    但是,如果不明白如何将列表转换为数据框,这将失败:

    > myList <- list(a = c(1, 2, 3), b = c(4, 5, 6, 7))
    > myDf <- as.data.frame(myList)
    

    错误(函数(...,row.names = NULL,check.rows = FALSE,check.names = TRUE,: 参数意味着不同的行数:3、4

    注意:答案指向问题的标题,可能会跳过问题的一些细节

    【讨论】:

    • 请注意,在问题的输入中,这只是一种工作方式。 OP 要求 132 行和 20 列,但这给出了 20 行和 132 列。
    • 对于您的示例,输入不同长度的失败,目前尚不清楚所需的结果是什么......
    • @Gregor True,但问题标题是“R - 数据框列表”。该问题的许多访问者和投票的人都没有确切的 OP 问题。根据问题标题,他们只是寻找一种将列表转换为数据框的方法。我自己也有同样的问题,我发布的解决方案解决了我的问题
    • 是的,只是注意到。不投反对票。在答案中注意到它做了类似的事情——但与其他答案明显不同——可能会很好。
    【解决方案3】:

    我也想提出这个解决方案。尽管它看起来与其他解决方案相似,但它使用了 plyr 包中的 rbind.fill。这在列表缺少列或 NA 值的情况下是有利的。

    l <- replicate(10,as.list(sample(letters,10)),simplify = FALSE)
    
    res<-data.frame()
    for (i in 1:length(l))
      res<-plyr::rbind.fill(res,data.frame(t(unlist(l[i]))))
    
    res
    

    【讨论】:

      【解决方案4】:

      此方法使用tidyverse 包(purrr)。

      名单:

      x <- as.list(mtcars)
      

      将其转换为数据框(更具体地说是tibble):

      library(purrr)
      map_df(x, ~.x)
      

      编辑:2021 年 5 月 30 日

      这实际上可以通过dplyr中的bind_rows()函数来实现。

      x <- as.list(mtcars)
      dplyr::bind_rows(x)
      
       A tibble: 32 x 11
           mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
         <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
       1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
       2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
       3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
       4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
       5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
       6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
       7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
       8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
       9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
      10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
      # ... with 22 more rows
      

      【讨论】:

        【解决方案5】:

        或者你可以使用 tibble 包(来自 tidyverse):

        #create examplelist
        l <- replicate(
          132,
          as.list(sample(letters, 20)),
          simplify = FALSE
        )
        
        #package tidyverse
        library(tidyverse)
        
        #make a dataframe (or use as_tibble)
        df <- as_data_frame(l,.name_repair = "unique")
        
        
        
        

        【讨论】:

        • 它创建 df 有 20 行和 132 列,但它应该是其他的
        【解决方案6】:

        2020 年 7 月更新:

        参数stringsAsFactors 的默认值现在是default.stringsAsFactors(),而FALSE 作为其默认值。


        假设您的列表名为l

        df <- data.frame(matrix(unlist(l), nrow=length(l), byrow=TRUE))
        

        上面会将所有字符列转换为因子,为避免这种情况,您可以在 data.frame() 调用中添加一个参数:

        df <- data.frame(matrix(unlist(l), nrow=132, byrow=TRUE),stringsAsFactors=FALSE)
        

        【讨论】:

        • 如果您的数据并非全部属于同一类型,请注意此处。传递一个矩阵意味着所有数据都将被强制转换为一个通用类型。 IE。如果您有一列字符数据和一列数字数据,则数字数据将被 matrix() 强制转换为字符串,然后都被 data.frame() 强制转换为因子。
        • 在列表中有缺失值或在数据框中包含 NA 的情况下,最好的方法是什么?
        • @Dave:为我工作...见这里r-fiddle.org/#/fiddle?id=y8DW7lqL&version=3
        • 如果你有字符数据类型,也要小心 - data.frame 会将其转换为因子。
        • @nico 有没有办法将列表元素名称保留为 df 中的 colnames 或 rownames?
        【解决方案7】:

        修复样本数据,使其与原始描述“每个项目都是长度为 20 的列表”匹配

        mylistlist <- replicate(
          132,
          as.list(sample(letters, 20)),
          simplify = FALSE
        )
        

        我们可以将它转换成这样的数据框:

        data.frame(t(sapply(mylistlist,c)))
        

        sapply 将其转换为矩阵。 data.frame 将矩阵转换为数据框。

        导致:

        【讨论】:

        • 迄今为止最好的答案!其他解决方案都没有正确的类型/列名。谢谢!
        • 您打算c 在这里扮演什么角色,列表数据的一个实例?哦,等等,c 代表连接函数,对吧?对@mnel 对 c 的使用感到困惑。我也同意@dhandler,在我的用例中,正确的列名是一个有价值的需求。绝妙的解决方案。
        • 正确 - 标准 c 函数;来自?cCombine Values into a Vector or List
        • 不适用于问题中提供的示例数据
        • 这不会生成列表的data.frame吗?
        【解决方案8】:

        试试collapse::unlist2d('unlist to data.frame'的简写):

        l <- replicate(
          132,
          list(sample(letters, 20)),
          simplify = FALSE
        )
        
        library(collapse)
        head(unlist2d(l))
          .id.1 .id.2 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
        1     1     1  e  x  b  d  s  p  a  c  k   z   q   m   u   l   h   n   r   t   o   y
        2     2     1  r  t  i  k  m  b  h  n  s   e   p   f   o   c   x   l   g   v   a   j
        3     3     1  t  r  v  z  a  u  c  o  w   f   m   b   d   g   p   q   y   e   n   k
        4     4     1  x  i  e  p  f  d  q  k  h   b   j   s   z   a   t   v   y   l   m   n
        5     5     1  d  z  k  y  a  p  b  h  c   v   f   m   u   l   n   q   e   i   w   j
        6     6     1  l  f  s  u  o  v  p  z  q   e   r   c   h   n   a   t   m   k   y   x
        
        head(unlist2d(l, idcols = FALSE))
          V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
        1  e  x  b  d  s  p  a  c  k   z   q   m   u   l   h   n   r   t   o   y
        2  r  t  i  k  m  b  h  n  s   e   p   f   o   c   x   l   g   v   a   j
        3  t  r  v  z  a  u  c  o  w   f   m   b   d   g   p   q   y   e   n   k
        4  x  i  e  p  f  d  q  k  h   b   j   s   z   a   t   v   y   l   m   n
        5  d  z  k  y  a  p  b  h  c   v   f   m   u   l   n   q   e   i   w   j
        6  l  f  s  u  o  v  p  z  q   e   r   c   h   n   a   t   m   k   y   x
        

        【讨论】:

          【解决方案9】:

          我发现的每个解决方案似乎只适用于list 中的每个对象都具有相同的length。当list 中的对象的length 不等于length 时,我需要将list 转换为data.frame。以下是我提出的基本R 解决方案。这无疑是非常低效的,但它似乎确实有效。

          x1 <- c(2, 13)
          x2 <- c(2, 4, 6, 9, 11, 13)
          x3 <- c(1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13)
          my.results <- list(x1, x2, x3)
          
          # identify length of each list
          my.lengths <- unlist(lapply(my.results, function (x) { length(unlist(x))}))
          my.lengths
          #[1]  2  6 20
          
          # create a vector of values in all lists
          my.values <- as.numeric(unlist(c(do.call(rbind, lapply(my.results, as.data.frame)))))
          my.values
          #[1]  2 13  2  4  6  9 11 13  1  1  2  3  3  4  5  5  6  7  7  8  9  9 10 11 11 12 13 13
          
          my.matrix <- matrix(NA, nrow = max(my.lengths), ncol = length(my.lengths))
          
          my.cumsum <- cumsum(my.lengths)
          
          mm <- 1
          
          for(i in 1:length(my.lengths)) {
          
               my.matrix[1:my.lengths[i],i] <- my.values[mm:my.cumsum[i]]
          
               mm <- my.cumsum[i]+1
          
          }
          
          my.df <- as.data.frame(my.matrix)
          my.df
          #   V1 V2 V3
          #1   2  2  1
          #2  13  4  1
          #3  NA  6  2
          #4  NA  9  3
          #5  NA 11  3
          #6  NA 13  4
          #7  NA NA  5
          #8  NA NA  5
          #9  NA NA  6
          #10 NA NA  7
          #11 NA NA  7
          #12 NA NA  8
          #13 NA NA  9
          #14 NA NA  9
          #15 NA NA 10
          #16 NA NA 11
          #17 NA NA 11
          #18 NA NA 12
          #19 NA NA 13
          #20 NA NA 13
          

          【讨论】:

            【解决方案10】:

            map_ 函数与for 循环一起使用怎么样?这是我的解决方案:

            list_to_df <- function(list_to_convert) {
              tmp_data_frame <- data.frame()
              for (i in 1:length(list_to_convert)) {
                tmp <- map_dfr(list_to_convert[[i]], data.frame)
                tmp_data_frame <- rbind(tmp_data_frame, tmp)
              }
              return(tmp_data_frame)
            }
            

            其中map_dfr 将每个列表元素转换为data.frame,然后rbind 将它们合并在一起。

            在你的情况下,我猜是:

            converted_list <- list_to_df(l)
            

            【讨论】:

            • 1.结果错误 2. 循环效率低下。最好使用嵌套地图:map(list_to_convert, ~map_dfr(., data.frame)) 但仍然是错误的。
            【解决方案11】:

            一个简短的(但可能不是最快的)方法是使用base r,因为数据框只是一个list of equal length vectors。因此,您的输入列表和 30 x 132 data.frame 之间的转换将是:

            df <- data.frame(l)
            

            从那里我们可以将其转置为 132 x 30 矩阵,并将其转换回数据帧:

            new_df <- data.frame(t(df))
            

            作为单行:

            new_df <- data.frame(t(data.frame(l)))
            

            这些行名看起来很烦人,但你总是可以用

            重命名它们

            rownames(new_df) &lt;- 1:nrow(new_df)

            【讨论】:

            • 为什么这被否决了?我想知道,所以我不会继续传播错误信息。
            • 我之前肯定做过这个,使用 data.frame 和 t 的组合!我猜投反对票的人觉得有更好的方法,尤其是那些不会弄乱名字的方法。
            • 这是一个好点,如果您想在列表中保留名称,我想这也是不正确的。
            【解决方案12】:

            对于使用purrr 系列解决方案的并行(多核、多会话等)解决方案,请使用:

            library (furrr)
            plan(multisession) # see below to see which other plan() is the more efficient
            myTibble <- future_map_dfc(l, ~.x)
            

            l 是列表。

            要对最有效的plan() 进行基准测试,您可以使用:

            library(tictoc)
            plan(sequential) # reference time
            # plan(multisession) # benchamark plan() goes here. See ?plan().
            tic()
            myTibble <- future_map_dfc(l, ~.x)
            toc()
            

            【讨论】:

              【解决方案13】:

              根据列表的结构,有一些tidyverse 选项可以很好地处理不等长度的列表:

              l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
                      , b = list(var.1 = 4, var.2 = 5)
                      , c = list(var.1 = 7, var.3 = 9)
                      , d = list(var.1 = 10, var.2 = 11, var.3 = NA))
              
              df <- dplyr::bind_rows(l)
              df <- purrr::map_df(l, dplyr::bind_rows)
              df <- purrr::map_df(l, ~.x)
              
              # all create the same data frame:
              # A tibble: 4 x 3
                var.1 var.2 var.3
                <dbl> <dbl> <dbl>
              1     1     2     3
              2     4     5    NA
              3     7    NA     9
              4    10    11    NA
              

              您还可以混合使用向量和数据框:

              library(dplyr)
              bind_rows(
                list(a = 1, b = 2),
                data_frame(a = 3:4, b = 5:6),
                c(a = 7)
              )
              
              # A tibble: 4 x 2
                    a     b
                <dbl> <dbl>
              1     1     2
              2     3     5
              3     4     6
              4     7    NA
              

              【讨论】:

              • 这个 dplyr::bind_rows 函数运行良好,即使很难处理源自 JSON 的列表。从 JSON 到令人惊讶的干净数据框。不错。
              • @sbha 我尝试使用 df X2 can' t 从整数转换为字符
              【解决方案14】:

              tibble 包有一个函数enframe(),它通过将嵌套的list 对象强制为嵌套的tibble(“整洁”数据框)对象来解决这个问题。这是来自R for Data Science的一个简短示例:

              x <- list(
                  a = 1:5,
                  b = 3:4, 
                  c = 5:6
              ) 
              
              df <- enframe(x)
              df
              #> # A tibble: 3 × 2
              #>    name     value
              #>   <chr>    <list>
              #>    1     a <int [5]>
              #>    2     b <int [2]>
              #>    3     c <int [2]>
              

              由于您的列表中有多个嵌套l,您可以使用unlist(recursive = FALSE) 删除不必要的嵌套以仅获得一个层次列表,然后传递给enframe()。我使用tidyr::unnest() 将输出取消嵌套到单个级别的“整洁”数据框中,该数据框有两列(一列用于name 组,另一列用于value 组的观察)。如果您想要使列变宽,您可以使用 add_column() 添加一个列,该列仅重复值的顺序 132 次。然后只需 spread() 值。


              library(tidyverse)
              
              l <- replicate(
                  132,
                  list(sample(letters, 20)),
                  simplify = FALSE
              )
              
              l_tib <- l %>% 
                  unlist(recursive = FALSE) %>% 
                  enframe() %>% 
                  unnest()
              l_tib
              #> # A tibble: 2,640 x 2
              #>     name value
              #>    <int> <chr>
              #> 1      1     d
              #> 2      1     z
              #> 3      1     l
              #> 4      1     b
              #> 5      1     i
              #> 6      1     j
              #> 7      1     g
              #> 8      1     w
              #> 9      1     r
              #> 10     1     p
              #> # ... with 2,630 more rows
              
              l_tib_spread <- l_tib %>%
                  add_column(index = rep(1:20, 132)) %>%
                  spread(key = index, value = value)
              l_tib_spread
              #> # A tibble: 132 x 21
              #>     name   `1`   `2`   `3`   `4`   `5`   `6`   `7`   `8`   `9`  `10`  `11`
              #> *  <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
              #> 1      1     d     z     l     b     i     j     g     w     r     p     y
              #> 2      2     w     s     h     r     i     k     d     u     a     f     j
              #> 3      3     r     v     q     s     m     u     j     p     f     a     i
              #> 4      4     o     y     x     n     p     i     f     m     h     l     t
              #> 5      5     p     w     v     d     k     a     l     r     j     q     n
              #> 6      6     i     k     w     o     c     n     m     b     v     e     q
              #> 7      7     c     d     m     i     u     o     e     z     v     g     p
              #> 8      8     f     s     e     o     p     n     k     x     c     z     h
              #> 9      9     d     g     o     h     x     i     c     y     t     f     j
              #> 10    10     y     r     f     k     d     o     b     u     i     x     s
              #> # ... with 122 more rows, and 9 more variables: `12` <chr>, `13` <chr>,
              #> #   `14` <chr>, `15` <chr>, `16` <chr>, `17` <chr>, `18` <chr>,
              #> #   `19` <chr>, `20` <chr>
              

              【讨论】:

              • 引用 OP:“有没有一种快速的方法可以将此结构转换为具有 132 行和 20 列数据的数据框?”所以也许你需要一个扩展步骤或其他东西。
              • 啊,是的,只需要一个可以传播的索引列。我会尽快更新。
              【解决方案15】:

              对于深度嵌套列表的一般情况具有 3 个或更多级别,例如从嵌套 JSON 获得的列表:

              {
              "2015": {
                "spain": {"population": 43, "GNP": 9},
                "sweden": {"population": 7, "GNP": 6}},
              "2016": {
                "spain": {"population": 45, "GNP": 10},
                "sweden": {"population": 9, "GNP": 8}}
              }
              

              首先考虑melt()的方法将嵌套列表转换为高格式:

              myjson <- jsonlite:fromJSON(file("test.json"))
              tall <- reshape2::melt(myjson)[, c("L1", "L2", "L3", "value")]
                  L1     L2         L3 value
              1 2015  spain population    43
              2 2015  spain        GNP     9
              3 2015 sweden population     7
              4 2015 sweden        GNP     6
              5 2016  spain population    45
              6 2016  spain        GNP    10
              7 2016 sweden population     9
              8 2016 sweden        GNP     8
              

              接着是dcast(),然后再次扩大到一个整洁的数据集中,其中每个变量形成一列,每个观察形成一行:

              wide <- reshape2::dcast(tall, L1+L2~L3) 
              # left side of the formula defines the rows/observations and the 
              # right side defines the variables/measurements
                  L1     L2 GNP population
              1 2015  spain   9         43
              2 2015 sweden   6          7
              3 2016  spain  10         45
              4 2016 sweden   8          9
              

              【讨论】:

                【解决方案16】:

                有时您的数据可能是相同长度的向量列表的列表。

                lolov = list(list(c(1,2,3),c(4,5,6)), list(c(7,8,9),c(10,11,12),c(13,14,15)) )
                

                (内部向量也可以是列表,但我正在简化以使其更易于阅读)。

                然后您可以进行以下修改。请记住,您可以一次取消列出一个级别:

                lov = unlist(lolov, recursive = FALSE )
                > lov
                [[1]]
                [1] 1 2 3
                
                [[2]]
                [1] 4 5 6
                
                [[3]]
                [1] 7 8 9
                
                [[4]]
                [1] 10 11 12
                
                [[5]]
                [1] 13 14 15
                

                现在使用其他答案中提到的您最喜欢的方法:

                library(plyr)
                >ldply(lov)
                  V1 V2 V3
                1  1  2  3
                2  4  5  6
                3  7  8  9
                4 10 11 12
                5 13 14 15
                

                【讨论】:

                • plyr 被弃用,取而代之的是 dplyr
                【解决方案17】:
                l <- replicate(10,list(sample(letters, 20)))
                a <-lapply(l[1:10],data.frame)
                do.call("cbind", a)
                

                【讨论】:

                  【解决方案18】:

                  这最终对我有用:

                  do.call("rbind", lapply(S1, as.data.frame))

                  【讨论】:

                    【解决方案19】:

                    扩展@Marek 的回答:如果您想避免字符串变成因素并且效率不是问题,请尝试

                    do.call(rbind, lapply(your_list, data.frame, stringsAsFactors=FALSE))
                    

                    【讨论】:

                      【解决方案20】:

                      假设您的列表名为L

                      data.frame(Reduce(rbind, L))
                      

                      【讨论】:

                      • 不错的一个! @Alex Brown 的解决方案与您的解决方案有一个区别,由于某种原因,您的路线会产生以下警告消息:`警告消息:在 data.row.names(row.names,rowsi,i) 中:一些 row.names 重复: 3,4 --> row.names NOT used'
                      • 非常好!!在这里为我工作:stackoverflow.com/questions/32996321/…
                      • 效果很好,除非列表中只有一个元素:data.frame(Reduce(rbind, list(c('col1','col2')))) 生成一个具有 2 行 1 列 的数据框(我预计 1 行 2 列)跨度>
                      • 您可以使用 purr 函数“reduce”,而不是使用基本函数“Reduce”,如:reduce(L, rbind)。这会输出一个数据框,并假设列表 (L) 中的每个数据框都以相同的方式组织(即包含相同数量的相同顺序的列。
                      【解决方案21】:

                      Reshape2 产生与上述 plyr 示例相同的输出:

                      library(reshape2)
                      l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
                                , b = list(var.1 = 4, var.2 = 5, var.3 = 6)
                                , c = list(var.1 = 7, var.2 = 8, var.3 = 9)
                                , d = list(var.1 = 10, var.2 = 11, var.3 = 12)
                      )
                      l <- melt(l)
                      dcast(l, L1 ~ L2)
                      

                      产量:

                        L1 var.1 var.2 var.3
                      1  a     1     2     3
                      2  b     4     5     6
                      3  c     7     8     9
                      4  d    10    11    12
                      

                      如果您几乎没有像素,可以在 1 行中使用 recast() 完成所有操作。

                      【讨论】:

                      • 我认为 reshape2 已被 dplyr、tidyr 等弃用
                      【解决方案22】:

                      rbind

                      do.call(rbind.data.frame, your_list)
                      

                      编辑:以前的版本返回 listdata.frame 而不是向量(正如 @IanSudbery 在 cmets 中指出的那样)。

                      【讨论】:

                      • 为什么这行得通,但 rbind(your_list) 返回一个 1x32 列表矩阵?
                      • @eykanal do.callyour_list 的元素作为参数传递给rbind。相当于rbind(your_list[[1]], your_list[[2]], your_list[[3]], ....., your_list[[length of your_list]])
                      • 这个方法会遇到null的情况。
                      • @FrankWANG 但是这种方法不是为空的情况而设计的。 your_list 要求包含相同大小的向量。 NULL 的长度为 0,因此它应该失败。
                      • 这个方法似乎返回了正确的对象,但是在检查对象时,你会发现列是列表而不是向量,如果你不期望它可能会导致问题.
                      【解决方案23】:

                      data.table 具有函数rbindlist,它是do.call(rbind, list(...)) 的超快速实现。

                      它可以将listsdata.framesdata.tables 的列表作为输入。

                      library(data.table)
                      ll <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
                        , b = list(var.1 = 4, var.2 = 5, var.3 = 6)
                        , c = list(var.1 = 7, var.2 = 8, var.3 = 9)
                        , d = list(var.1 = 10, var.2 = 11, var.3 = 12)
                        )
                      
                      DT <- rbindlist(ll)
                      

                      这会返回一个继承自 data.framedata.table

                      如果您真的想要转换回data.frame,请使用as.data.frame(DT)

                      【讨论】:

                      • 关于最后一行,setDF 现在允许通过引用返回 data.frame。
                      • 对于我的包含 30k 个项目的列表,rbindlist 的工作速度比 ldply 快
                      • 这确实超级快!
                      【解决方案24】:

                      更多答案,以及此问题的答案时间: What is the most efficient way to cast a list as a data frame?

                      不产生带有列表而不是列向量的数据框的最快方法似乎是(来自 Martin Morgan 的回答):

                      l <- list(list(col1="a",col2=1),list(col1="b",col2=2))
                      f = function(x) function(i) unlist(lapply(x, `[[`, i), use.names=FALSE)
                      as.data.frame(Map(f(l), names(l[[1]])))
                      

                      【讨论】:

                        【解决方案25】:

                        您可以使用plyr 包。 例如表单的嵌套列表

                        l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
                              , b = list(var.1 = 4, var.2 = 5, var.3 = 6)
                              , c = list(var.1 = 7, var.2 = 8, var.3 = 9)
                              , d = list(var.1 = 10, var.2 = 11, var.3 = 12)
                              )
                        

                        现在长度为 4,l 中的每个列表都包含另一个长度为 3 的列表。 现在你可以运行了

                          library (plyr)
                          df <- ldply (l, data.frame)
                        

                        并且应该得到与@Marek 和@nico 的答案相同的结果。

                        【讨论】:

                        • 很好的答案。我能解释一下它是如何工作的吗?它只是为每个列表条目返回一个数据框?
                        • 恕我直言,最好的答案。它返回一个诚实的 data.frame。所有数据类型(字符、数字等)都已正确转换。如果列表具有不同的数据类型,它们将全部转换为使用matrix 方法的字符。
                        • 此处提供的示例不是问题提供的示例。这个答案在原始数据集上的结果是不正确的。
                        • 非常适合我!并且设置了结果数据框中的列名!发送
                        • plyr 被弃用,取而代之的是 dplyr
                        猜你喜欢
                        • 2020-04-15
                        • 2020-04-17
                        • 2022-11-14
                        • 2013-09-26
                        相关资源
                        最近更新 更多