【问题标题】:How to rbind every nth element of a list using base R?如何使用base R绑定列表的每个第n个元素?
【发布时间】:2021-12-22 07:31:49
【问题描述】:

我有一个包含不同数据框的列表。列表的每个第 n 个数据帧都具有相同的结构。列表有点像这样:

my_list <- list(list(data.frame(a= rnorm(10), b= rnorm(10)),
                 data.frame(abc= letters[1:10])),
                list(data.frame(a= rnorm(10), b= rnorm(10)),
                 data.frame(abc= letters[11:20])))

我想rbind.data.frame 每个列表的第一个数据框和每个列表的第二个数据框。因此,我的预期结果是:

list(rbind.data.frame(my_list[[1]][[1]], my_list[[2]][[1]]),
     rbind.data.frame(my_list[[1]][[2]], my_list[[2]][[2]]))

在此示例中,每个列表有两个数据帧,但在我的情况下,数据帧的数量可能会在再次运行代码时发生变化。所以我需要一个绑定每个第 n 个列表的通用解决方案。我怎样才能用基础 R 做到这一点?它必须是基础 R。

【问题讨论】:

    标签: r list bind


    【解决方案1】:

    我们可以使用purrr中的transpose,然后将它们与bind_rows绑定

    library(dplyr)
    library(purrr)
    my_list %>% 
        transpose %>% 
        map(bind_rows)
    

    -输出

    [[1]]
                 a           b
    1  -0.40658840  1.09857513
    2  -2.32161471 -0.56369035
    3   0.69620650  0.06641017
    4   0.36916329  0.89903129
    5   1.48593464 -0.01071652
    6  -0.42947609  0.73611717
    7   0.30131109  1.30576324
    8   0.23362408  0.09240332
    9  -0.06293769  0.20475366
    10 -0.33819360 -0.92148073
    11  0.86595847  0.97195603
    12  0.07233009  0.18503846
    13 -0.36391964 -0.34366129
    14 -1.47300138  1.02652189
    15  0.51676676  0.57571450
    16  0.24114748  0.26843610
    17 -0.86102844 -1.08844244
    18 -1.08346107  2.30818241
    19 -1.22420213 -1.06698399
    20 -0.55371072  0.67798167
    
    [[2]]
       abc
    1    a
    2    b
    3    c
    4    d
    5    e
    6    f
    7    g
    8    h
    9    i
    10   j
    11   k
    12   l
    13   m
    14   n
    15   o
    16   p
    17   q
    18   r
    19   s
    20   t
    

    或使用base R

    lapply(split(do.call(c, my_list), rep(c(TRUE, FALSE), 
          length(my_list))), \(x) do.call(rbind, x))
    

    -输出

    $`FALSE`
       abc
    1    a
    2    b
    3    c
    4    d
    5    e
    6    f
    7    g
    8    h
    9    i
    10   j
    11   k
    12   l
    13   m
    14   n
    15   o
    16   p
    17   q
    18   r
    19   s
    20   t
    
    $`TRUE`
                 a           b
    1  -0.40658840  1.09857513
    2  -2.32161471 -0.56369035
    3   0.69620650  0.06641017
    4   0.36916329  0.89903129
    5   1.48593464 -0.01071652
    6  -0.42947609  0.73611717
    7   0.30131109  1.30576324
    8   0.23362408  0.09240332
    9  -0.06293769  0.20475366
    10 -0.33819360 -0.92148073
    11  0.86595847  0.97195603
    12  0.07233009  0.18503846
    13 -0.36391964 -0.34366129
    14 -1.47300138  1.02652189
    15  0.51676676  0.57571450
    16  0.24114748  0.26843610
    17 -0.86102844 -1.08844244
    18 -1.08346107  2.30818241
    19 -1.22420213 -1.06698399
    20 -0.55371072  0.67798167
    

    【讨论】:

    • 感谢您的快速回答,但我正在寻找基本 R 解决方案(请参阅问题)
    • @machine 抱歉,没有看到最后一部分。我更新了
    • 太棒了(+1)! lapply(..., \(x) do.call(rbind, x)) 中的 \x 有什么作用?我将其更改为 function(x) 并得到相同的输出。我应该注意一些区别吗?谢谢
    • @machine 这只是 R 最新版本中 lambda 函数的一个紧凑选项。除了 \(x) 之外,还有 |&gt; 运算符,它模仿了 @ 的一些功能987654334@ 来自 magrittr
    【解决方案2】:

    选择您感兴趣的元素,例如

    lapply(my_list, `[[`, 1)
    

    对于第一个 data.frame。然后使用do.call()rbind 选定的data.frames列表

    do.call(rbind, lapply(my_list, `[[`, 1))
    

    用一个提取任何列表元素i的函数来概括这一点

    FUN <- function(x, i)
        do.call(rbind, lapply(x, `[[`, i))
    

    并使用lapply() 生成您感兴趣的多个data.frames

    lapply(1:2, FUN, x = my_list)
    

    【讨论】:

      猜你喜欢
      • 2022-01-25
      • 2015-01-12
      • 2020-01-10
      • 1970-01-01
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 2021-02-21
      • 1970-01-01
      相关资源
      最近更新 更多