【问题标题】:Make dataframe from list of lists but each element a column从列表列表中创建数据框,但每个元素都是一列
【发布时间】:2020-05-26 22:41:01
【问题描述】:

我想从列表列表中创建一个数据框,其中生成的数据框对于每个元素都有一列,并且行是单独的。这很难解释,所以我将尝试制作一个示例来处理。

假设我的清单如下:

myList <- list(
  list(L=c(1,2,3),a=c(1,2,3),b=c(1,2,3)),
  list(L=c(4,5,6),a=c(4,5,6),b=c(4,5,6)),
  list(L=c(7,8,9),a=c(7,8,9),b=c(7,8,9)))

生成的数据框如下所示:

df <- data.frame(ind = c(1,2,3),
  L.1 = c(1,4,7),L.2 = c(2,5,8), L.3 = c(3,6,9),
  a.1 = c(1,4,7),a.2 = c(2,5,8), a.3 = c(3,6,9),
  b.1 = c(1,4,7),b.2 = c(2,5,8), b.3 = c(3,6,9))

我尝试过使用

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

df &lt;- bind_rows(myList, .id="column_label")

但这些会为每个人生成三行,而不是所需的输出。

我也尝试过使用: df &lt;- bind_cols(myList) 但这会将列划分为每个列表。

知道该怎么做吗?

谢谢, 夏娃

【问题讨论】:

    标签: r list dataframe nested-lists


    【解决方案1】:

    如果名称总是一一匹配,您可以这样做,

    do.call(rbind, lapply(myList, unlist))
    #     L1 L2 L3 a1 a2 a3 b1 b2 b3
    #[1,]  1  2  3  1  2  3  1  2  3
    #[2,]  4  5  6  4  5  6  4  5  6
    #[3,]  7  8  9  7  8  9  7  8  9
    

    【讨论】:

    • 非常感谢您的回答 - 效果很好!我刚刚在您的函数周围添加了as.data.frame(),以确保它是一个数据框:)
    【解决方案2】:
    librayr(purrr) # load the purrr library
    library(magrittr) # load the magrittr library
    myList %>% 
        map(unlist) %>% # for each element of myList, apply the unlist function which makes it a vector of 9 floats.
        map(as.list) %>% # transform this vector into a list
        map_dfr(data.frame) # and then transofrm this list into a data.frame row.
    

    【讨论】:

    • 您能否详细说明您的答案?也许通过解释代码?
    • 感谢您的回答。同意@Twenty,你能解释一下每个部分的作用吗?我以前从未使用过magittr,但看起来它会是一个有用的工具!
    • magrittr 确实是一个非常方便的库:它提供了管道 %&gt;% ,它允许语法 x %&gt;% f(y) 相当于 f(x,y) 甚至 x %&gt;% f 相当于 @987654328 @。这允许将功能彼此通过管道传递。另一方面,purrr::map 也是一个很棒的功能。您应该查看它们的文档。
    【解决方案3】:

    一个purrr 选项可以是:

    myList %>%
     map_df(~ bind_rows(unlist(.)))
    
      L1 L2 L3 a1 a2 a3 b1 b2 b3
    1  1  2  3  1  2  3  1  2  3
    2  4  5  6  4  5  6  4  5  6
    3  7  8  9  7  8  9  7  8  9
    

    还包括 ind 列,并添加了dplyr

    myList %>%
     map_df(~ bind_rows(unlist(.))) %>%
     mutate(ind = 1:n())
    

    【讨论】:

    • 非常感谢您的回答!我不经常使用purrr,所以也很高兴看到这个选项!
    【解决方案4】:

    您也可以在使用sapply() 后转置为unlist()

    as.data.frame(t(sapply(myList, unlist)))
      L1 L2 L3 a1 a2 a3 b1 b2 b3
    1  1  2  3  1  2  3  1  2  3
    2  4  5  6  4  5  6  4  5  6
    3  7  8  9  7  8  9  7  8  9
    

    【讨论】:

    • 感谢您的回答-它有效!您介意澄清t() 的作用吗?
    • 当然——t() 转置矩阵。如果你一点一点地运行它,你会看到sapply() 的结果做了你需要的,它只需要转置。
    猜你喜欢
    • 2017-01-12
    • 2022-11-18
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    相关资源
    最近更新 更多