Reputation: 147
I want to merge two lists of data frames. The lists have different length and the data frames in them also.
ls(df_list1)
[1] "0" "1" "14" "15" "16" "19" "2" "23" "25" "29" "3" "31" "32" "33" "36" "38" "4" "46" "48" "5" "57" "6" "61" "63"
[25] "7" "8" "9"
ls(df_list2)
[1] "0" "1" "10" "15" "16" "17" "19" "2" "24" "26" "3" "30" "32" "33" "34" "37" "39" "4" "47" "49" "5" "58" "6" "62"
[25] "64" "7" "8" "9"
I want to merge every dataframe from df_list1 with every dataframe from df_list2.
Tried this, but I can`t save all the combinations to test, just the last merge from the cycle.
test=list()
for (i in 1:length(df_list1){
for (j in 1:length(df_list2){
test[[i]] <- inner_join(df_list1[[i]], df_list2[[j]], by="variable")
}
}
Maybe something like this:
df_list1 <- list("0"=data.frame("variable" = c(2,4,8), "variable2" = c(13,14,53), "variable1" = "2019-05-31"),
"1"=data.frame("variable" = c(3,7,2), "variable2" = c(53,68,41), "variable1" = "2019-05-31"),
"4"=data.frame("variable" = c(6,5,6), "variable2" = c(24,52,83), "variable1" = "2019-05-31"))
df_list2 <- list("0"=data.frame("variable" = c(2,8,3), "variable2" = c(72,25,37), "variable1" = "2019-05-31"),
"3"=data.frame("variable" = c(2,7,6), "variable2" = c(24,62,45), "variable1" = "2019-05-31"),
"4"=data.frame("variable" = c(9,5,8), "variable2" = c(34,74,58), "variable1" = "2019-05-31"))
Upvotes: 0
Views: 65
Reputation: 5788
Base R solution:
df <- data.frame(Reduce(function(x, y){
merge(x, y, by = intersect(colnames(x), colnames(y)), all = TRUE)},
c(setNames(df_list1, c(paste0("X_", names(df_list1)))),
setNames(df_list2, c(paste0("X_", names(df_list2)))))))
Upvotes: 0
Reputation: 101343
I am not sure what is your desired output. With the data you provided in your post, I tried to make the minimal changes to your code to see if that is what you want:
Since you attempt to save all combinations, you should use for
loop like below, where test[[length(test)+1]]
is to update the test
with newly generated combination:
test=list()
for (i in 1:length(df_list1)) {
for (j in 1:length(df_list2)) {
test[[length(test)+1]] <- inner_join(df_list1[[i]], df_list2[[j]], by="variable")
}
}
If you want to produce a data frame of all combinations, then you can make it as below
df <- Reduce(rbind,test)
such that
> df
variable variable2.x variable1.x variable2.y variable1.y
1 2 13 2019-05-31 72 2019-05-31
2 8 53 2019-05-31 25 2019-05-31
3 2 13 2019-05-31 24 2019-05-31
4 8 53 2019-05-31 58 2019-05-31
5 3 53 2019-05-31 37 2019-05-31
6 2 41 2019-05-31 72 2019-05-31
7 7 68 2019-05-31 62 2019-05-31
8 2 41 2019-05-31 24 2019-05-31
9 6 24 2019-05-31 45 2019-05-31
10 6 83 2019-05-31 45 2019-05-31
11 5 52 2019-05-31 74 2019-05-31
Upvotes: 1
Reputation: 101343
I use the following dummy data frames df1
and df2
as examples to show you how to make it (if I understand your purpose correctly)
df1 <- data.frame(a = 1:5, b = 6:10)
df2 <- data.frame(c = 1:6, d = 7:12)
which look like
> df1
a b
1 1 6
2 2 7
3 3 8
4 4 9
5 5 10
> df2
c d
1 1 7
2 2 8
3 3 9
4 4 10
5 5 11
6 6 12
Given that df1
is shorter than df2
, I fill df1
with NA
to make it has the same length as df2
:
df1 <- data.frame(lapply(df1, `length<-`,nrow(df2)))
and then the merged all combinations of df1
and df2
can be obtained via nested sapply()
, i.e.,
df <- data.frame(unlist(lapply(df1, function(p) lapply(df2, function(q) data.frame(p,q))), recursive = F))
such that
> df
a.c.p a.c.q a.d.p a.d.q b.c.p b.c.q b.d.p b.d.q
1 1 1 1 7 6 1 6 7
2 2 2 2 8 7 2 7 8
3 3 3 3 9 8 3 8 9
4 4 4 4 10 9 4 9 10
5 5 5 5 11 10 5 10 11
6 NA 6 NA 12 NA 6 NA 12
Upvotes: 0