iacobus
iacobus

Reputation: 597

pass a character vector as the funs argument for summarize_at

I'm working on a function that takes an argument funs that is a string of functions to be applied to a set of variables vars. The simplest way to do this seemed to be to use dplyr's summarize_at and the SE version of funs function.

This works with the functions that are built-in R but doesn't seem to work with user-defined functions. It reports an error that it can't find the user-defined function. However, summarize_at works when done "manually."

This function is part of a larger function that produces a box for a Shiny Dashboard. I'd prefer not to have (and have to maintain) a different Shiny module for each type of box (each function and function argument combination).

A minimal reproducible example is below:

# function to compute summary stat
compute_box_value <- function(data, vars, funs) {
  f = funs_(funs)
  result <- data %>% 
    summarize_at(.cols = vars, .funs = f)
}

# simple user defined function that gets count of rows with certain values of x
equals <- function(x, test_value) {
  sum(x %in% test_value)
}

x <- data.frame(value = sample(1:5, 10, TRUE))

vars <- c("value")

# this works
print(compute_box_value(x, vars, "mean(., na.rm = TRUE)"))

# this works
summarize_at(x, vars, .funs = "equals", test_value = 1)

# this doesn't work (error: couldn't find function equals)
print(compute_box_value(x, vars, "equals(., test_value = 1)"))

Upvotes: 1

Views: 449

Answers (1)

Steven Beaupr&#233;
Steven Beaupr&#233;

Reputation: 21641

You need to use the formula (~) instead of string:

print(compute_box_value(x, vars, ~equals(., test_value = 1)))

Which gives:

#  value
#1     3

From the documentation:

It’s best to use a formula because a formula captures both the expression to evaluate and the environment where the evaluation occurs. This is important if the expression is a mixture of variables in a data frame and objects in the local environment:

Upvotes: 1

Related Questions