【问题标题】:Transforming a nested data frame with varying number of elements转换具有不同数量元素的嵌套数据框
【发布时间】:2017-12-08 21:14:36
【问题描述】:

我有一个数据框,其中包含一列嵌套数据框,其中包含 1 或 2 列和 n 行。它看起来像下面示例中的 df

'data.frame':   3 obs. of  2 variables:
 $ vector:List of 3
  ..$ : chr "p1"
  ..$ : chr "p2"
  ..$ : chr "p3"
 $ lists :List of 3
  ..$ :'data.frame':    2 obs. of  2 variables:
  .. ..$ n1: Factor w/ 2 levels "a","b": 1 2
  .. ..$ n2: Factor w/ 2 levels "1","2": 1 2
  ..$ :'data.frame':    1 obs. of  1 variable:
  .. ..$ n1: Factor w/ 1 level "d": 1
  ..$ :'data.frame':    1 obs. of  2 variables:
  .. ..$ n1: Factor w/ 1 level "e": 1
  .. ..$ n2: Factor w/ 1 level "3": 1

df 可以像这样重新创建:

v <- c("p1", "p2", "p3")
l <- list(data.frame(n1 = c("a", "b"), n2 = c("1", "2")), data.frame(n1 = "d"), data.frame(n1 = "e", n2 = "3"))
df <- as.data.frame(cbind(v, l))

我想将其转换为如下所示的数据框:

[v] [n1] [n2]

p1  a  1

p1  b  2

p2  d  NA

p3  e  3
  • n1 和 n2 位于不同的列中
  • 如果第i行的数据框有n行,第i行的向量元素应该重复n次
  • 如果n1或n2中没有内容,应该有NA

我尝试过使用 tidyr::unnest 但收到以下错误

 unnest(df)
Error: All nested columns must have the same number of elements.

有没有人更好地了解如何将数据框转换为所需的格式?

【问题讨论】:

    标签: r dataframe tidyr


    【解决方案1】:

    使用purrr::pmap_df,在df的每一行中,我们将vl组合成一个数据帧,然后将所有数据帧组合成一个数据帧。

    library(tidyverse)
    
    pmap_df(df, function(v,l) {
      data.frame(v,l)
    })
    
       v n1   n2
    1 p1  a    1
    2 p1  b    2
    3 p2  d <NA>
    4 p3  e    3
    

    【讨论】:

      【解决方案2】:

      这将避免按行操作,如果您有很多行,这将很重要。

      library(data.table)
      
      rbindlist(df$l, fill = T, id = 'row')[, v := df$v[row]][]
      #   row n1 n2  v
      #1:   1  a  1 p1
      #2:   1  b  2 p1
      #3:   2  d NA p2
      #4:   3  e  3 p3
      

      【讨论】:

      • 效果很好!关于这个还有一个问题:如果有超过1列v的内容应该重复,如何使用这个函数?
      • 也许是setDT(df); rbindlist(df$l, fill = T, id = 'row')[, c(.SD, df[row, -'l'])]
      【解决方案3】:

      使用dplyrtidyr 的解决方案。 suppressWarnings 不是必需的。因为在创建数据框的时候,有因子列,suppressWarnings是为了抑制组合因子时的警告信息。

      library(dplyr)
      library(tidyr)
      
      df1 <- suppressWarnings(df %>%
        mutate(v = unlist(.$v)) %>%
        unnest())
      df1
      #    v n1   n2
      # 1 p1  a    1
      # 2 p1  b    2
      # 3 p2  d <NA>
      # 4 p3  e    3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        相关资源
        最近更新 更多