Reputation: 55
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
x
's format in d1
and thenx
in d2
to be of the same format, producing NA
's along the way, andrbind
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.
Upvotes: 0
Views: 272
Reputation: 51914
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
Upvotes: 1
Reputation: 173793
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
Upvotes: 3