I'd like to bind (row-wise) two dataframes of different column size, but enforce that the columns' formats of the first dataframe be kept.
Example:
d1 <- tibble(x = 1, y = "b") # before edit: d1 <- tibble(x = 1)
d2 <- tibble(x = c(2, "a"))
When employing, say, plyr
's rbind.fill
, the combined column will be of the character type. However, I'd like to obtain the (final) result
str(data.frame(x = c(1, 2, NA)))
#> 'data.frame': 3 obs. of 1 variable:
#> $ x: num 1 2 NA
I suppose for this to work, I'd have to
- look up
x
's format ind1
and then - force
x
ind2
to be of the same format, producingNA
's along the way, and rbind
thereafter.
The problem is, I cannot come up with an elegant solution to this little problem. Any help will be much appreciated!
Edited to account for data frames of different column size.
CodePudding user response:
Your approach is reasonable and can be done in a single line:
bind_rows(d1, map2_df(d1, d2, ~ `class<-`(.y, class(.x))))
#> # A tibble: 3 x 1
#> x
#> <dbl>
#> 1 1
#> 2 2
#> 3 NA
CodePudding user response:
In base R with match.fun
:
common <- intersect(names(d1), names(d2))
d2[common] <- lapply(common, function(x) {
match.fun(paste0("as.", class(d1[[x]])))(d2[[x]])
})
dplyr::bind_rows(d1, d2)
output
# A tibble: 3 × 1
x
<dbl>
1 1
2 2
3 NA