【问题标题】:Converting a list of lists into a data.frame in R将列表列表转换为 R 中的 data.frame
【发布时间】:2019-02-06 16:17:13
【问题描述】:

我正在尝试将列表列表转换为data.frame。我意识到这个问题已被多次问过,但我找不到适用于我的情况的较早答案。

这里有几个较早的帖子:

How to flatten a list of lists?

R list of lists to data.frame

到目前为止,我看到的最佳答案是 Benjamin Christoffersen 在上面的第二个链接中给出的,但在我的情况下,每个子列表只有一个值,我缺少观察结果,并且我的列表有我希望保留的名称。

这是我的示例数据集:

AA <- list(my.col1 =    1, my.col2 =    4, my.col3 = NULL, my.col4 = NULL)
BB <- list(my.col1 = NULL, my.col2 = NULL, my.col3 = NULL, my.col4 = NULL)
CC <- list(my.col1 =   13, my.col2 =    8, my.col3 =    2, my.col4 =   10)
DD <- list(my.col1 = NULL, my.col2 = NULL, my.col3 =   -5, my.col4 =    7)

my.stuff <- list(AA, BB, CC, DD)
names(my.stuff) <- c("AA", "BB", "CC", "DD")
my.stuff

这是所需的data.frame

desired.object <- read.table(text = '
     my.var   my.col1 my.col2 my.col3 my.col4
        AA       1       4    NULL    NULL
        BB    NULL    NULL    NULL    NULL
        CC      13       8       2      10
        DD    NULL    NULL      -5       7', 
stringsAsFactors = FALSE, header = TRUE, na.strings = "NULL")
desired.object
#  my.var my.col1 my.col2 my.col3 my.col4
#1     AA       1       4      NA      NA
#2     BB      NA      NA      NA      NA
#3     CC      13       8       2      10
#4     DD      NA      NA      -5       7

我可以得到看起来相似的输出,但它根本不是我想要的格式:

my.stuff2    <- do.call(rbind, my.stuff)
my.stuff2
#    my.col1 my.col2 my.col3 my.col4
# AA 1       4       NULL    NULL   
# BB NULL    NULL    NULL    NULL   
# CC 13      8       2       10     
# DD NULL    NULL    -5      7

对不起,如果这个问题已经得到解答。

【问题讨论】:

    标签: r list dataframe


    【解决方案1】:

    这个怎么样?

    do <- as.data.frame(do.call(rbind, lapply(my.stuff, as.vector)))
    do <- cbind(my.var=rownames(do), do)
    do[do == "NULL"] <- NA
    

    结果

    > do
       my.var my.col1 my.col2 my.col3 my.col4
    AA     AA       1       4      NA      NA
    BB     BB      NA      NA      NA      NA
    CC     CC      13       8       2      10
    DD     DD      NA      NA      -5       7
    

    编辑:

    如果我们不想像@akrun 合理建议的那样将列表作为列对象,我们可以这样做:

    u <- as.character(unlist(my.stuff, recursive=FALSE))
    u[u == "NULL"] <- NA
    do <- matrix(as.integer(u), nrow=4, byrow=TRUE, 
                 dimnames=list(NULL, names(my.stuff[[1]])))
    do <- data.frame(my.var=names(my.stuff), do, stringsAsFactors=FALSE)
    

    测试:

    > all.equal(str(do), str(desired.object))
    'data.frame':   4 obs. of  5 variables:
     $ my.var : chr  "AA" "BB" "CC" "DD"
     $ my.col1: int  1 NA 13 NA
     $ my.col2: int  4 NA 8 NA
     $ my.col3: int  NA NA 2 -5
     $ my.col4: int  NA NA 10 7
    'data.frame':   4 obs. of  5 variables:
     $ my.var : chr  "AA" "BB" "CC" "DD"
     $ my.col1: int  1 NA 13 NA
     $ my.col2: int  4 NA 8 NA
     $ my.col3: int  NA NA 2 -5
     $ my.col4: int  NA NA 10 7
    [1] TRUE
    

    【讨论】:

      【解决方案2】:

      我们可以使用递归map

      library(tidyverse)
      map_df(my.stuff, ~ map_df(.x,  ~ 
                            replace(.x, is.null(.x), NA)), .id = "my.var")  
      # A tibble: 4 x 5
      #  my.var my.col1 my.col2 my.col3 my.col4
      #  <chr>    <dbl>   <dbl>   <dbl>   <dbl>
      #1 AA           1       4      NA      NA
      #2 BB          NA      NA      NA      NA
      #3 CC          13       8       2      10
      #4 DD          NA      NA      -5       7
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-17
        • 1970-01-01
        • 1970-01-01
        • 2016-06-17
        • 1970-01-01
        • 2014-05-17
        • 2017-12-22
        • 1970-01-01
        相关资源
        最近更新 更多