1

I have a named list of functions, where the names(transform_functions) correspond to the column names and the functions are the transformations to be applied to every specific column. For example, in the example below, transform_functions$height is function(x) x+1, so I expect the equivalent outcome of starwars |> mutate(height = height + 1).

In total, this should do the equivalent of starwars |> mutate(height = height + 1, birth_year = birth_year / 2)

Is there a non-cluttery way to write this? reduce2 works as shown below, but it seems I must be reinventing something here. across is not it, as it applies a specified set of functions to multiple columns.

library(dplyr)
library(purrr)

transform_functions <- list(
  height = function(x) x+1,
  birth_year = function(x) x/2
)



# This works, but is hardly readable and seems like a lot of hassle
purrr::reduce2(
  .x = transform_functions, 
  .y = names(transform_functions),
  .f = function(df, fun, col) 
    df |> mutate(!!col := fun(!!sym(col))),
  .init = starwars)

# Obviously doesn't work, since it would assign (rather than execute) the function to each column 
starwars |>
  mutate(!!!transform_functions)

3 Answers 3

3

If you convert/wrap your transform_functions into unevaluated expressions, you can splice them into a mutate call:

transform_expressions = transform_functions |>
    imap(\(f, n) bquote(.(f)(.(as.name(n)))))
starwars |>
    mutate(!!! transform_expressions)

This becomes especially convenient if you can directly encode the expressions, rather than having to convert them from functions:

transform_expressions = alist(
    height = height + 1,
    birth_year = birth_year / 2
)
Sign up to request clarification or add additional context in comments.

Comments

3

One option is to use imap_dfc() and an across() call:

library(dplyr)
library(purrr)

starwars %>%
  mutate(imap_dfc(transform_functions, ~ across(all_of(.y), .x)))

Comments

0
starwars |>
  mutate(across(names(transform_functions), ~ transform_functions[[cur_column()]](.x)))

Mhm. I don't like cur_column() but I guess it works

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.