I'm trying to write a function that will wrap dplyr::coalesce()
, and will take in a data object and column names to coalesce. So far, my attempts have failed.
Example data
library(dplyr)
df <-
data.frame(col_a = c("bob", NA, "bob", NA, "bob"),
col_b = c(NA, "danny", NA, NA, NA),
col_c = c("paul", NA, NA, "paul", NA))
## col_a col_b col_c
## 1 bob <NA> paul
## 2 <NA> danny <NA>
## 3 bob <NA> <NA>
## 4 <NA> <NA> paul
## 5 bob <NA> <NA>
Taking a stub at writing a custom function
coalesce_plus_1 <- function(data, vars) {
data %>%
mutate(coalesced_col = coalesce(!!! rlang::syms(tidyselect::vars_select(names(.), vars))))
}
coalesce_plus_2 <- function(data, vars) {
data %>%
mutate(coalesced_col = coalesce(!!! rlang::syms(vars)))
}
coalesce_plus_3 <- function(data, vars) {
data %>%
mutate(coalesced_col = coalesce({{ vars }}))
}
The results...
coalesce_plus_1()
df %>%
coalesce_plus_1(data = ., vars = c(col_a, col_b, col_c))
Error: object 'col_a' not found.
However:
df %>%
coalesce_plus_1(data = ., vars = all_of(starts_with("col")))
## col_a col_b col_c coalesced_col
## 1 <NA> <NA> paul paul
## 2 <NA> danny <NA> danny
## 3 bob <NA> <NA> bob
## 4 <NA> <NA> paul paul
## 5 bob <NA> <NA> bob
coalesce_plus_2()
df %>%
coalesce_plus_2(data = ., vars = c(col_a, col_b, col_c))
Error in lapply(.x, .f, ...) : object 'col_a' not found
And also
df %>%
coalesce_plus_2(data = ., vars = all_of(starts_with("col")))
Error:
starts_with()
must be used within a selecting function. i See https://tidyselect.r-lib.org/reference/faq-selection-context.html. Runrlang::last_error()
to see where the error occurred.
coalesce_plus_3()
df %>%
coalesce_plus_3(data = ., vars = c(col_a, col_b, col_c))
Error: Problem with
mutate()
inputcoalesced_col
. x Inputcoalesced_col
can't be recycled to size 5. i Inputcoalesced_col
iscoalesce(c(col_a, col_b, col_c))
. i Inputcoalesced_col
must be size 5 or 1, not 15.
And also
df %>%
coalesce_plus_3(data = ., vars = all_of(starts_with("col")))
Error: Problem with
mutate()
inputcoalesced_col
. xstarts_with()
must be used within a selecting function. i See https://tidyselect.r-lib.org/reference/faq-selection-context.html. i Inputcoalesced_col
iscoalesce(all_of(starts_with("col")))
.
Bottom line
How can I write a custom function for coalesce()
that will take in a data object and specific column names to coalesce, allowing both specific naming e.g., c(col_a, col_b, col_c)
and helper functions e.g., starts_with("col")
in the function's vars
argument?