Home > database >  Merge dataframes with same name within a list when dataframe lengths differ
Merge dataframes with same name within a list when dataframe lengths differ

Time:07-19

I have a list that contains several dataframes. My goal is to merge the dataframes that share the same name together. However, although two dataframes may share the same name, they do not always share the same number of rows. I followed this SO post until I encountered my issue below. I have included a reprex below that is an extension of this issue.

library(tidyverse)

d1 <- data.frame(id = "111", y1 = c(1, 2, 3), y2 = c(4, 2, 6))
d2 <- data.frame(id = "111" , y1 = c(2, 1), y2 = c(4, 4)) # missing a row
d3 <- data.frame(id = "222", y1 = c(2, 2, 3), y2 = c(2, 2, 6))
d4 <- data.frame(id = "222" , y1 = c(3, 2), y2 = c(2, 4)) # missing a row
d5 <- data.frame(id = "333", y1 = c(5, 5, 3), y2 = c(0, 2, 6))
d6 <- data.frame(id = "333" , y1 = c(3, 6, 7), y2 = c(1, 9, 4))

lst <- list(d1, d2, d3, d4, d5, d6)
rm(d1, d2, d3, d4, d5, d6)
names(lst) <- c("111", "111", "222", "222", "333", "333")
lstdf <- map(split(lst, names(lst)), bind_cols)
#> Error in `.f()`:
#> ! Can't recycle `..1` (size 3) to match `..2` (size 2).

Using the do.call(cbind, x) option causes a similar issue. My goal is to "cut off" the extra row and have the minimum number of rows for any ID number (if the ID number contains differing number of rows between its two dataframes). Any help is appreciated.

CodePudding user response:

We may use a function that pads NA when the lengths are not same i.e. cbind.na from qpcR does it

library(purrr)
 map(split(lst, names(lst)),  ~ reduce(.x, qpcR:::cbind.na))

CodePudding user response:

You can use

lst <- lapply(split(lst, names(lst)) , \(x) do.call(rbind , x))

lapply(lst , \(x) {row.names(x) <- NULL ; x})
  • output
$`111`
   id y1 y2
1 111  1  4
2 111  2  2
3 111  3  6
4 111  2  4
5 111  1  4

$`222`
   id y1 y2
1 222  2  2
2 222  2  2
3 222  3  6
4 222  3  2
5 222  2  4

$`333`
   id y1 y2
1 333  5  0
2 333  5  2
3 333  3  6
4 333  3  1
5 333  6  9
6 333  7  4

  • Related