I have an list object like below.
df1 <- data_frame(ID = paste0(LETTERS[1],1:4), valueA = seq(0.1,0.4,0.1), Category= "Apples", valueDEF = seq(0.1,0.4,0.1), valueDEF2 = seq(0.1,0.4,0.1) )
df2 <- data_frame(ID = paste0(LETTERS[1],5:8), valueB = seq(0.1,0.4,0.1), Category= "Apples2")
df3 <- data_frame(ID = paste0(LETTERS[1],9:12), valueC = seq(0.1,0.4,0.1), Category= "Apples3")
list1 <- list(df1, df2, df3);list1
[[1]]
# A tibble: 4 × 5
ID valueA Category valueDEF valueDEF2
<chr> <dbl> <chr> <dbl> <dbl>
1 A1 0.1 Apples 0.1 0.1
2 A2 0.2 Apples 0.2 0.2
3 A3 0.3 Apples 0.3 0.3
4 A4 0.4 Apples 0.4 0.4
[[2]]
# A tibble: 4 × 3
ID valueB Category
<chr> <dbl> <chr>
1 A5 0.1 Apples2
2 A6 0.2 Apples2
3 A7 0.3 Apples2
4 A8 0.4 Apples2
[[3]]
# A tibble: 4 × 3
ID valueC Category
<chr> <dbl> <chr>
1 A9 0.1 Apples3
2 A10 0.2 Apples3
3 A11 0.3 Apples3
4 A12 0.4 Apples3
And I would like to merge them into 1 data frame based on the common column names.
Expected Answer
ID Category
A1 Apples
A2 Apples
A3 Apples
A4 Apples
A5 Apples2
A6 Apples2
A7 Apples2
A8 Apples2
A9 Apples3
A10 Apples3
A11 Apples3
A12 Apples3
How to get around this? Many thanks in advance.
>Solution :
We could use intersect().
- For this we apply colnames to each data frame in the list with
lapply(). - The resulting list is then passed to
Reduce()with the
intersect()function. - Finally we use
bind_rows()to get a single data frame:
library(dplyr) #bind_rows()
common_cols <- Reduce(intersect, lapply(list1, colnames))
df_all <- bind_rows(list1)[common_cols]
ID Category
<chr> <chr>
1 A1 Apples
2 A2 Apples
3 A3 Apples
4 A4 Apples
5 A5 Apples2
6 A6 Apples2
7 A7 Apples2
8 A8 Apples2
9 A9 Apples3
10 A10 Apples3
11 A11 Apples3
12 A12 Apples3