Hi following Programming with dplyr I noticed that one can add a name using quo_name. I was wondering how to do this for multiple columns, eg. like a quos_name of sorts. E.g.:
my_mutate <- function(df, expr) {
expr <- enquo(expr)
mean_name <- paste0("mean_", quo_name(expr))
sum_name <- paste0("sum_", quo_name(expr))
mutate(df,
!!mean_name := mean(!!expr),
!!sum_name := sum(!!expr)
)
}
becomes
my_mutate <- function(df, ...) {
exprs <-quos(...)
mean_names <- paste0("mean_", quos_name(exprs))
sum_names <- paste0("sum_", quos_name(exprs))
mutate(df,
!!!mean_names := mean(!!!exprs),
!!!sum_names := sum(!!!exprs)
)
}
ie. adding the mean and sum columns for all columns specified in ... , of course this is only as an example and quos_names don't exist. It would be very helpful if there is a way of doing this.
I know it is possible to do something like this in data.table DT[,(Col_names):=lapply(Cols,mean)]
for instance (This code does not work, but I have done something like this before).
DISCLAIMER: While
mutate_at
proposed by @aosmith is in my opinion the best and simplest solution, I think it might be instructive to see how the problem could be approached usingrlang
tools, ifmutate_at
didn't exist. For science!As mentioned in the comments, you will want to look into
purrr::map()
family of functions. You will also run into a separate problem with!!!mean_names := mean(!!!exprs)
because the!!!
splice operator cannot be used on the left hand of the assignment.The best
rlang
approach is to compose yourmutate
expressions as a named list. Usequo
to perform expression arithmetic andstringr::str_c
(orpaste0
as you've been doing) for string arithmetic:BONUS: You will notice that we are repeating a chunk of code in our definition of expressions above. We can pull that out into a standalone function that automatically constructs expressions with the provided function and names those expressions accordingly:
We can now use the new
mutator
function to re-definemy_mutate
as a simple one-liner:It seems that you found an answer using
mutate_at
, but in case you need to do that in another context, I'll add the following way.If you use the following function, you'll see that
quos(...)
returns a list of quosures corresponding to your arguments.So you can easily convert the result of
quos
to a list (or vector) of characters applyingquo_name
to each quoted arguments using one ofsapply
orlapply
: