I am trying to merge each dataframe in a list of dataframes with a different column of a single dataframe. That is, the dataframe in list element 1 should be merged with row 1 of the single dataframe, the dataframe in list element 2 should be merged with row 2 of the single dataframe and so on. It's easier to understand with an example.
Here is my list of dataframes:
df1 <- data.frame(col1 = 11:14, col2 = 11:14)
df2 <- data.frame(col1 = 12:15, col2 = 12:15)
df3 <- data.frame(col1 = 13:16, col2 = 13:16)
df_list <- list(df1, df2, df3)
So df_list
looks like this:
[[1]]
col1 col2
1 11 11
2 12 12
3 13 13
4 14 14
[[2]]
col1 col2
1 12 12
2 13 13
3 14 14
4 15 15
[[3]]
col1 col2
1 13 13
2 14 14
3 15 15
4 16 16
Here is my single dataframe:
df_to_merge <- data.frame(col3 = 1:3, col4 = 4:6)
col3 col4
1 1 4
2 2 5
3 3 6
I can easily achieve the result I want with a loop:
what_i_want <- list()
for (i in 1:nrow(df_to_merge)) {
what_i_want[[i]] <- merge.data.frame(df_list[[i]], df_to_merge[i, ])
}
Which gives:
[[1]]
col1 col2 col3 col4
1 11 11 1 4
2 12 12 1 4
3 13 13 1 4
4 14 14 1 4
[[2]]
col1 col2 col3 col4
1 12 12 2 5
2 13 13 2 5
3 14 14 2 5
4 15 15 2 5
[[3]]
col1 col2 col3 col4
1 13 13 3 6
2 14 14 3 6
3 15 15 3 6
4 16 16 3 6
Is there a more elegant way to do this with a combination of eg lapply()
and apply()
? Or mapply()
? I tried, but the only thing I could manage was to combine each element of the list with each row of the single dataframe, which I don't want.
Thanks in advance for any creative solutions!
You're basically there now:
what_i_want <- lapply(seq_along(df_list), function(i) { merge.data.frame(df_list[[i]], df_to_merge[i,]) })
Result:
> what_i_want
[[1]]
col1 col2 col3 col4
1 11 11 1 4
2 12 12 1 4
3 13 13 1 4
4 14 14 1 4
[[2]]
col1 col2 col3 col4
1 12 12 2 5
2 13 13 2 5
3 14 14 2 5
4 15 15 2 5
[[3]]
col1 col2 col3 col4
1 13 13 3 6
2 14 14 3 6
3 15 15 3 6
4 16 16 3 6
You can split
df_to_merge
at each row and use Map
to cbind
Map(cbind, df_list, split(df_to_merge, seq_len(nrow(df_to_merge))))
#[1]]
# col1 col2 col3 col4
#1 11 11 1 4
#2 12 12 1 4
#3 13 13 1 4
#4 14 14 1 4
#[[2]]
# col1 col2 col3 col4
#1 12 12 2 5
#2 13 13 2 5
#3 14 14 2 5
#4 15 15 2 5
#[[3]]
# col1 col2 col3 col4
#1 13 13 3 6
#2 14 14 3 6
#3 15 15 3 6
#4 16 16 3 6
A tidyverse
way of the same logic could be
library(dplyr)
library(purrr)
map2(df_list, df_to_merge %>% group_split(row_number(), keep = FALSE), cbind)
Here is a base R solution using lapply()
and cbind()
dfout <- lapply(seq(df_list), function(k) cbind(df_list[[k]],df_to_merge[k,],row.names = NULL))
such that
> dfout
[[1]]
col1 col2 col3 col4
1 11 11 1 4
2 12 12 1 4
3 13 13 1 4
4 14 14 1 4
[[2]]
col1 col2 col3 col4
1 12 12 2 5
2 13 13 2 5
3 14 14 2 5
4 15 15 2 5
[[3]]
col1 col2 col3 col4
1 13 13 3 6
2 14 14 3 6
3 15 15 3 6
4 16 16 3 6
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.