Reputation: 389
I'd like to pass a list of variables to a function, but I'm confused by the quoting and quosures.
Normally, I want to return a df after some kind of data management has been done--after the function has been applied to several variables.
As it is the function works ok (just slightly modified from a users stack exchange answer to another question), but the calls are repetitive in this example. Any suggestions, points to readings or etc., I'd appreciate.
library(tidyverse)
library(rlang)
library(tidyselect)
data <- data.frame(ageeeeoo = c(1,NA,3,NA,5),
ageeeaah = c(NA,2,NA,4,NA),
numnumd = c(1,NA,3,NA,5),
numfoofe = c(NA,2,NA,4,NA))
newfun <- function (var1) {
var1<-enquo(var1)
data<<-mutate(data,(!!as_name(var1)) := coalesce(!!! syms(vars_select(names(data),
starts_with(as_name(var1))))))
}
newfun(age)
newfun(num)
ageeeeoo ageeeaah numnumd numfoofe age num
1 NA 1 NA 1 1
NA 2 NA 2 2 2
3 NA 3 NA 3 3
NA 4 NA 4 4 4
5 NA 5 NA 5 5
I tried reviewing the dplyr programming documents and a few other stack exchange QA but the quoting throws me off. I've tried using alist and list but get errors.
listofvars<-c("age","num")
newfun <- function (...) {
data<<-mutate(data,(!!!rlang::syms(...)) := coalesce(!!! syms(vars_select(names(data),
starts_with(!!!quos(...))))))
}
newfun(listofvars)
Upvotes: 0
Views: 163
Reputation: 12640
library(tidyverse)
library(rlang)
library(tidyselect)
data <- data.frame(ageeeeoo = c(1,NA,3,NA,5),
ageeeaah = c(NA,2,NA,4,NA),
numnumd = c(1,NA,3,NA,5),
numfoofe = c(NA,2,NA,4,NA))
newfun2 <- function (data, ...) {
vars <- ensyms(..., .named = TRUE)
needed <- map(
vars,
~vars_select(names(data), starts_with(as_name(.x))) %>%
{quo(coalesce(!!!syms(.)))}
)
mutate(data, !!!needed)
}
data <- newfun2(data, age, num)
list_of_vars <- exprs(age, num)
data <- newfun2(data, !!!list_of_vars)
data
This first captures the input from ...
as symbols. It can uses purrr::map
to generate a list of coalesce
operations. These are then supplied to mutate
. I’ve rewritten the code so as not to modify the global environment within a function; most R code works like this, so in general variables won’t be altered except by explicit assignment.
The rlang help and Hadley Wickham’s advanced R are great resources.
Upvotes: 1