1

I have a data.frame with numerical data and a function that takes the column names as arguments. How do I call the function with those columns as arguments? Something like python's unpacking.

The reason I can't just hard-code it is that the column names, the number of columns, and the function itself changes - but always so that the column names match the function arguments.

Here is a simple version of the problem.

func = function(a, b, c) a * b^2 + c
df = data.frame(a = rnorm(10), b = rnorm(10), c = rnorm(10))
df %>%
    mutate(result = func(.))  # what to do here that doesn't involve "a", "b", "c"?

I have tried a this solution involving rowwise() but it is awfully slow. func can do vectorized computation.

My current solution is quite ugly:

call_str = paste0("func(", paste0(colnames(df), " = df$", colnames(df), collapse=","), ")")
result = eval(parse(text = call_str))

In this example, call_str is

"func(a = df$a, b = df$b, c = df$c)"
Jonas Lindeløv
  • 5,442
  • 6
  • 31
  • 54

1 Answers1

2

Use do.call:

df %>% mutate(result = do.call("func", .))

or invoke which is a similar function in purrr:

library(purrr)
df %>% mutate(result = invoke("func", .))

or lift which acts on the function itself producing a new function:

library(purrr)
df %>% mutate(result = lift(func)(.))
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341