Mar
Mar

Reputation: 147

Merging lists of data frames with different length

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

Answers (3)

hello_friend
hello_friend

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

ThomasIsCoding
ThomasIsCoding

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

ThomasIsCoding
ThomasIsCoding

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

Related Questions