Home > Enterprise >  How to rbind every nth element of a list using base R?
How to rbind every nth element of a list using base R?

Time:11-10

I have a list containing different dataframes. Every nth dataframe of the list has the same structure. The list is somewhat like this:

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])))

I want to rbind.data.frame the first dataframe of each list and the second dataframe of each list. Thus, my expected result is:

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

In this example there are two dataframes per list but in my case the number of dataframes can change while running the code another time. So I need a general solution that binds every nth list. How can I do this with base R? It must be base R.

CodePudding user response:

Select the element that you're interested in with something like

lapply(my_list, `[[`, 1)

for the first data.frame. Then use do.call() to rbind the list of selected data.frames

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

Generalize this with a function that extracts any list element i

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

and use lapply() to generate the multiple data.frames you're interested in

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

CodePudding user response:

We may use transpose from purrr and then bind them with bind_rows

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

-output

[[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

Or using base R

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

-output

$`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
  • Related