【问题标题】:Unnest list of lists of data frames, containing NAs数据帧列表的未嵌套列表,包含 NA
【发布时间】:2021-11-06 07:05:19
【问题描述】:

我有一个嵌套数据列表,其中包含两个数据框的列表,每个数据框如下所示:

mylist <- list(
              list(
                p = data.frame(
                    id = "01",
                    stringsAsFactors = F
                    ),
                c = data.frame(
                    text = c("one", "two"),
                    from = c("A", "B"),
                    stringsAsFactors = F
                    )
                  ),
               list(
                  p = data.frame(
                    id = "02",
                    stringsAsFactors = F
                    ),
                  c = data.frame(
                    text = c("three", "four", "five"),
                    from = c("C", "D", "E"),
                    stringsAsFactors = F
                    )
                   ),
                list(
                    p = data.frame(
                      id = "03",
                      stringsAsFactors = F
                      ),
                    c = data.frame(
                      text = logical(0),
                      from = logical(0)
                      )
                    )
                  )

我想将此列表展平为一个数据帧,从“c”数据帧中的每个观察值一行,一个表示存储在“p”数据帧中的上述级别的“id”的列,以及非观察值充满了 NA。结果应如下所示:

df <- data.frame(
            p.id = c("01", "01", "02", "02", "02", "03"),
            c.text = c("one", "two", "three", "four", "five", NA),
            c.from = c("A", "B", "C", "D", "E", NA)
)

# 
# p.id c.text c.from
# 01    one      A
# 01    two      B
# 02  three      C
# 02   four      D
# 02   five      E
# 03   <NA>   <NA>

as.data.frame() 提供了一个非常简单的解决方案,它非常接近预期的结果,但在“c”数据框中有 0 个观察值时会中断。

mylist[[1]] %>% as.data.frame()
mylist[[3]] %>% as.data.frame()

我知道有关 stackoverflow 的类似问题 - 但我仔细阅读了几个线程,尝试了从 bind_rows() 到 jsonlite::flatten()、tidr::unnest() 或 data.table:: 的不同方法rbindlist() - 但没有让它工作。

非常感谢您的帮助!

【问题讨论】:

    标签: r


    【解决方案1】:

    这是tidyverse 解决方案:

    library(tidyverse)
    
    map(mylist, ~as_tibble(.)) %>% 
      enframe() %>% 
      unnest_longer(value) 
    

    这给了我们:

    # A tibble: 6 x 2
       name value$p$id $c$text $$from
      <int> <chr>      <chr>   <chr> 
    1     1 01         one     A     
    2     1 01         two     B     
    3     2 02         three   C     
    4     2 02         four    D     
    5     2 02         five    E     
    6     3 NA         NA      NA 
    

    【讨论】:

      【解决方案2】:

      我创建了一个辅助函数来组合pc

      foo <- function(x) {
        a <- x[[1]]
        b <- x[[2]]
        if (nrow(b) == 0) b[1, ] <- NA
        return(cbind(a, b))
      }
      

      然后我在每个元素上运行辅助函数并绑定行:

      do.call(rbind, lapply(mylist, foo))
      

      结果:

      > do.call(rbind, lapply(mylist, foo))
        id  text from
      1 01   one    A
      2 01   two    B
      3 02 three    C
      4 02  four    D
      5 02  five    E
      6 03  <NA> <NA>
      

      附:使用 R 基管道的结果相同:

      lapply(mylist, foo) |> do.call(what = rbind)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-04
        • 2018-12-02
        • 2019-11-10
        • 1970-01-01
        • 2017-05-26
        • 1970-01-01
        • 2019-10-24
        • 1970-01-01
        相关资源
        最近更新 更多