这样也可以:

x <- do.call(cbind, lapply(l, cbind))
x[sapply(x, is.null)] <- NA
data.frame(apply(x, 2, unlist))
#>   X1 X2
#> 1  1 11
#> 2  2 NA
#> 3 NA 33
#> 4  4 NA

    9lotus 我好奇的是这种数据是怎么得来的,感觉问题可能在上游解决会更合适。也就是说,如果上游能把 NULL 以 NA 的形式提供出来,那问题就好办多了。这问题里的核心坑就是 NULL。

    dapengde
    原来列表也可以以矩阵的样式展示出来吗,第一次知道。。。

    x <- do.call(cbind, lapply(l, cbind))
    x[sapply(x, is.null)] <- NA
    
    x
    #>      [,1] [,2]
    #> [1,] 1    11  
    #> [2,] 2    NA  
    #> [3,] NA   33  
    #> [4,] 4    NA
    str(x)
    #> List of 8
    #>  $ : num 1
    #>  $ : num 2
    #>  $ : logi NA
    #>  $ : num 4
    #>  $ : num 11
    #>  $ : logi NA
    #>  $ : num 33
    #>  $ : logi NA
    #>  - attr(*, "dim")= int [1:2] 4 2

    研究了下,感觉知道了些不该知道的东西 🤣

    matrix(1:8, 2)
    #>      [,1] [,2] [,3] [,4]
    #> [1,]    1    3    5    7
    #> [2,]    2    4    6    8
    matrix(as.list(1:8), 2)
    #>      [,1] [,2] [,3] [,4]
    #> [1,] 1    3    5    7   
    #> [2,] 2    4    6    8
    str(matrix(1:8, 2))
    #>  int [1:2, 1:4] 1 2 3 4 5 6 7 8
    str(matrix(as.list(1:8), 2))
    #> List of 8
    #>  $ : int 1
    #>  $ : int 2
    #>  $ : int 3
    #>  $ : int 4
    #>  $ : int 5
    #>  $ : int 6
    #>  $ : int 7
    #>  $ : int 8
    #>  - attr(*, "dim")= int [1:2] 2 4
    
    matrix(list(1, 'a', TRUE, 1 + 1i), 2)
    #>      [,1] [,2]
    #> [1,] 1    TRUE
    #> [2,] "a"  1+1i

    一个和大鹏大同小异的办法:

    l = list(l1 = list(1, 2, NULL, 4), l2 = list(11, NULL, 33, NULL))
    df <- do.call(cbind, l)
    df[df == "NULL"] = NA
    df
    #>   l1 l2
    #> 1  1 11
    #> 2  2 NA
    #> 3 NA 33
    #> 4  4 NA

    <sup>Created on 2022-04-15 by the reprex package (v2.0.1)</sup>

      Liechi 我最初写的跟你的这个类似,但是发现得到的数据结构有点复杂:

      > str(df)
      List of 8
       $ : num 1
       $ : num 2
       $ : logi NA
       $ : num 4
       $ : num 11
       $ : logi NA
       $ : num 33
       $ : logi NA
       - attr(*, "dim")= int [1:2] 4 2
       - attr(*, "dimnames")=List of 2
        ..$ : NULL
        ..$ : chr [1:2] "l1" "l2"

      所以前后增加了一些操作,目的只是为了得到一个简单的 data frame。

      不过,你这个解法启发我动了点歪脑筋,可以绕开烧脑的 lapply sapply apply 家族:

      df <- do.call(cbind, l)
      write.table(df, 'clipboard')
      read.table('clipboard', na.strings = 'NULL')

      Cloud2016 赞 data.table,确实一剑封喉。

      data.frame(t(data.table::rbindlist(l)))
      #> Warning in data.table::rbindlist(l): Column 3 [''] of item 1 is length 0. This
      #> (and 2 others like it) has been filled with NA (NULL for list columns) to make
      #> each item uniform.
      #>    X1 X2
      #> V1  1 11
      #> V2  2 NA
      #> V3 NA 33
      #> V4  4 NA
        l = list(l1 = list(1, 2, NULL, 4), l2 = list(11, NULL, 33, NULL))
        library(purrr)
        l %>% 
          flatten() %>% 
          matrix(ncol = 2) %>% 
          as.data.frame() %>% 
          set_names(names(l)) -> df
        df[df == "NULL"] = NA
        print(df)
        #>   l1 l2
        #> 1  1 11
        #> 2  2 NA
        #> 3 NA 33
        #> 4  4 NA

        <sup>Created on 2022-04-15 by the reprex package (v2.0.1)</sup>

        l = list(l1 = list(1, 2, NULL, 4), l2 = list(11, NULL, 33, NULL))
        l |> 
          tibble::as_tibble() |> 
          as.data.frame() -> df
        df[df == "NULL"] = NA
        print(df) 
        #>   l1 l2
        #> 1  1 11
        #> 2  2 NA
        #> 3 NA 33
        #> 4  4 NA

        <sup>Created on 2022-04-15 by the reprex package (v2.0.1)</sup>

        dapengde
        这个“歪脑筋”在 mac 和 linux 上不好用:

        l = list(l1 = list(1, 2, NULL, 4), l2 = list(11, NULL, 33, NULL))
        df <- do.call(cbind, l)
        write.table(df, 'clipboard')
        #> Error in file(file, ifelse(append, "a", "w")): 'mode' for the clipboard must be 'r' on Unix

        有一些办法可绕开这个困难,考虑到性价比,十动然拒。

        感谢诸君!心里暖暖的

        当之无愧的 R 的第一中文社区。

        @yihui 这个l 来自于同花顺的股票数据。刚开始在转换时,老是出错,最后发现 IFinD 用了 NULL

        Cloud2016 谢谢。尝试过,但需要转置,而且变量名好像会丢失,故作罢。

        plumber
        好快的刀!

        找到这么直接了当的解法,是个狼灭啊。

        不知道为什么,好像满足要求了。

        只是能别表现得这么天真无邪人畜无害吗?反差萌,太勾人 ;)

        1 个月 后

        plumber
        想起来这里最好加个 keep_empty = T,不然全为 NULL 的行会被删掉

        l = list(l1 = list(1, 2, NULL, 4), l2 = list(11, NULL, NULL, NULL))
        unnest(as_tibble(l))
        unnest(as_tibble(l), keep_empty = T)