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