Reputation: 2321
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.
Upvotes: 2
Views: 266
Reputation: 4425
You can use
lst <- lapply(split(lst, names(lst)) , \(x) do.call(rbind , x))
lapply(lst , \(x) {row.names(x) <- NULL ; x})
$`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
Upvotes: 1
Reputation: 887971
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))
Upvotes: 2