Rbind Corresponding Elements in Two or More Lists in R

Rbind corresponding elements in two or more lists in R

Assuming length of a and b is the same we can do

lapply(seq_along(a), function(x) rbind(a[[x]], b[[x]]))

#[[1]]
# timeseries t
#1 1 1
#2 7 3
#3 59 7
#4 2 2
#5 3 4
#6 5 6

#[[2]]
# timeseries t
#1 1 1
#2 7 3
#3 59 7
#4 60 20
#5 70 30
#6 80 40

seq_along generates sequence from 1 to length of the object. If you do

seq_along(a) #you would get output as
#[1] 1 2

as length(a) is 2. So we rbind the dataframe one by one rbind(a[[1]], b[[1]]) first, then rbind(a[[2]], b[[2]]) and so on. lapply ensures the final output is a list.

R - How to rbind two lists while alternating their list elements

A variation on @DiscoSuperfly's answer that will work with objects of uneven length, like:

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

An answer:

L <- list(a,b)
L <- lapply(L, `length<-`, max(lengths(L)))
do.call(rbind, do.call(Map, c(rbind, L)))

# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 2 3 4 5
#[2,] 3 4 5 6 7
#[3,] 2 3 4 5 6
#[4,] 4 5 6 7 8
#[5,] 1 1 1 1 1

Binding corresponding data frame elements of multiple lists in R (with gapply for function)

I got it to work! I'm sure there is a more elegant way to do this, but the following seems to do the job:

Reduce(function(x,y) Map(rbind, x, y),gapply(df, groups=df$variable, FUN=tfunction))

how to bind lists in R

We can use Map to rbind list element wise

Map(rbind, list1, list2)

With purrr::map2 :

purrr::map2(list1, list2, rbind)

How to rbind sublists in R

Use map() to extract the first element of each sublist.

library(purrr)

datalistpairs[[1]] %>% map_dfr(~ .[[1]])

# LAT LON
# 1 1 2
# 2 1 2

The corresponding base R solution:

do.call(rbind, lapply(datalistpairs[[1]], `[[`, 1))

Edit: How to apply to datalistpairs[[i]] where i = 1, 2, 3, ..., n

lapply(1:n, function(i){
do.call(rbind, lapply(datalistpairs[[i]], `[[`, 1))
})

Is there a way to bind multiple dataframes by a named list?

If I understand correctly, you have a character vector with the names of the objects you want to bind.
Your goal is to bind multiple dataframes into asingle dataframe using the "vector of names".

May I suggest to use mget() function to convert your character vector into actual object's names? This does not require to make a list.

Please see the code below:

# dummy data to test it
df1 <- head(mtcars, 2)
df2 <- head(mtcars, 3)
df3 <- head(mtcars, 4)

# your "vector of names"
lst.names <- list("df1","df2","df3") # the output of your loop
df.names <- do.call(rbind, lst.names)[, 1] # change the list to a character vector

# this seems to work
do.call(rbind, mget(df.names))

The output:

> do.call(rbind, mget(df.names)) 
mpg cyl disp hp drat wt qsec vs am gear carb
df1.Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
df1.Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
df2.Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
df2.Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
df2.Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
df3.Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
df3.Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
df3.Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
df3.Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1

In R, reorganize list based on element names (rbind and indicator variable)

It sounds like you're doing a lot of gymnastics because you have a specific form in mind. What I would suggest is first trying to make the data tidy. Without reading the link, the quick summary is to put your data into a single data frame, where it can be easily processed.

The quick version of the answer (here I've used lst instead of list for the name to avoid confusion with the built-in list) is to do this:

do.call(rbind,
lapply(seq(lst), function(i) {
lst[[i]]$type <- names(lst)[i]; lst[[i]]
})
)

What this will do is create a single data frame, with a column, "type", that contains the name of the list item in which that row appeared.

Using a slightly simplified version of your initial data:

lst <- list(A1=data.frame(x=rnorm(5)), A2=data.frame(x=rnorm(3)), B=data.frame(x=rnorm(5)))
lst
$A1
x
1 1.3386071
2 1.9875317
3 0.4942179
4 -0.1803087
5 0.3094100

$A2
x
1 -0.3388195
2 1.1993115
3 1.9524970

$B
x
1 -0.1317882
2 -0.3383545
3 0.8864144
4 0.9241305
5 -0.8481927

And then applying the magic function

df <- do.call(rbind,
lapply(seq(lst), function(i) {
lst[[i]]$type <- names(lst)[i]; lst[[i]]
})
)
df
x type
1 1.3386071 A1
2 1.9875317 A1
3 0.4942179 A1
4 -0.1803087 A1
5 0.3094100 A1
6 -0.3388195 A2
7 1.1993115 A2
8 1.9524970 A2
9 -0.1317882 B
10 -0.3383545 B
11 0.8864144 B
12 0.9241305 B
13 -0.8481927 B

From here we can process to our hearts content; with operations like df$subject <- gsub("[0-9]*", "", df$type) to extract the non-numeric portion of type, and tools like split can be used to generate the sub-lists that you mention in your question.

In addition, once it is in this form, you can use functions like by and aggregate or libraries like dplyr or data.table to do more advanced split-apply-combine operations for data analysis.

Bind rows of dataframes from one list to dataframes in another list

We can use Map here and rbind the two list

Map(rbind, Mylist1, Mylist2)

#[[1]]
# x z y
#1 1 2 3
#2 2 3 4
#3 5 7 10
#4 6 8 11
#5 7 9 12

#[[2]]
# x z y
#1 1 2 3
#2 2 3 4
#3 25 27 210
#4 26 28 211
#5 27 29 212

This is also similar to

mapply(rbind, Mylist1, Mylist2, SIMPLIFY = FALSE)

and

purrr::map2(Mylist1, Mylist2, rbind)

How to rbind, arrange and format data in a list of matrices resulting from a group split

The following uses lapply loops to get the desired binded matrices and the Kable output.

bindcity <- lapply(seq_along(cities), function(i){
rbind(LOM[[i]], LOM[[i+length(cities)]], LOM[[i+(length(cities)*2)]])
})

nicematrices <- lapply(bindcity, function (x) {
rownames(x) <- c("Age", "Working years", "Income", "Age (male)", "Working years (male)", "Age (female)", "Working years (female)")
colnames(x) <- c("n (valid)", "% (valid)", "Mean", "SD", "Median", "25% Quantile", "75% Quantile")
x
})

The two loops above can be simplified. However, the following lapply loop will not create the bindcity list. This is only important if this list is used after, which is not clear from the question. It is not used to create the Kable tables.

nicematrices <- lapply(seq_along(cities), function (i) {
x <- rbind(LOM[[i]], LOM[[i+length(cities)]], LOM[[i+(length(cities)*2)]])
rownames(x) <- c("Age", "Working years", "Income", "Age (male)", "Working years (male)", "Age (female)", "Working years (female)")
colnames(x) <- c("n (valid)", "% (valid)", "Mean", "SD", "Median", "25% Quantile", "75% Quantile")
x
})

Now for the Kable tables.

library(kableExtra)

kbl_list <- lapply(nicematrices, function(x){
kbl <- kable(x, caption = "Title") %>%
column_spec(1, bold = TRUE) %>%
kable_styling("striped",
bootstrap_options = "hover",
full_width = TRUE)
print(kbl)
})

Combine two data frames by rows (rbind) when they have different sets of columns

rbind.fill from the package plyr might be what you are looking for.



Related Topics



Leave a reply



Submit