Home > front end >  Row-bind two dataframes, but enforce that the columns' formats of the first dataframe be kept
Row-bind two dataframes, but enforce that the columns' formats of the first dataframe be kept

Time:11-09

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 in d1 and then
  • force x in d2 to be of the same format, producing NA'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
  • Related