'Use do.call to run a function with a given list of parameters by the end user
I have a function called tidy_normal() from TidyDensity package. This takes in exactly one parameter per arguement, example: .mean = 1
What I want to do is build a function that will take in a quoted string from a user and the parameter list like so:
tidy_multi_dist(
.tidy_dist = "tidy_normal",
.param_list = list(
.n = 50,
.mean = c(-1, 0, 1),
.sd = 1,
.num_sims = 1)
)
What I have so far is:
tidy_multi_dist <- function(
.tidy_dist = NULL,
.param_list = list()
) {
# Check param ----
if (is.null(.tidy_dist)) {
rlang::abort(
"Please enter a 'tidy_' distribution function like 'tidy_normal'
in quotes."
)
}
if (length(.param_list) == 0) {
rlang::abort(
"Please enter some parameters for your chosen 'tidy_' distribution."
)
}
# Call used ---
td <- as.character(.tidy_dist)
# Params ----
params <- .param_list
# Params for the call ----
n <- as.integer(params$.n)
num_sims <- as.integer(params$.num_sims)
x <- seq(1, num_sims, 1)
# Final parameter list
final_params_list <- params[which(!names(params) %in% c(".n", ".num_sims"))]
# Set the grid to make the calls ----
param_grid <- expand.grid(final_params_list)
df <- tidyr::expand_grid(
n = n,
param_grid,
sim = as.integer(x)
) #%>%
#group_by_all()
func_parm_list <- as.list(df)
# Run call on the grouped df ----
dff <- df %>%
dplyr::rowwise() %>%
dplyr::mutate(results = list(do.call(td, func_parm_list))) # fails here
#df %>% rowwise() %>% mutate(results = list(do.call(td, list(.n = n, .num_sims = num_sims,.mean = .mean, .sd = .sd)))) %>% unnest(results)
# Get the attributes to be used later on ----
atb <- dff$results[[1]] %>% attributes()
# Make Dist Type for column ----
dist_type <- stringr::str_remove(atb$tibble_type, "tidy_") %>%
stringr::str_replace_all(pattern = "_", " ") %>%
stringr::str_to_title()
# Get column names from the param_grid in order to make teh dist_type column ----
cols <- names(param_grid)
dff$dist_name <- paste0(
paste0(dist_type, " c("),
apply(dff[, cols], 1, paste0, collapse = ", "),
")"
)
df_unnested_tbl <- dff %>%
tidyr::unnest(results) %>%
dplyr::ungroup() %>%
dplyr::select(sim_number, dist_name, x:q) %>%
dplyr::mutate(dist_name = as.factor(dist_name)) %>%
dplyr::arrange(sim_number, dist_name)
# Attach attributes ----
attr(df_unnested_tbl, "all") <- atb
attr(df_unnested_tbl, "tbl") <- "tidy_multi_tibble"
# Return ----
return(df_unnested_tbl)
}
The error message I am getting is:
> df %>%
+ #dplyr::rowwise() %>%
+ dplyr::mutate(results = list(do.call(td, func_parm_list)))
Error in `dplyr::mutate()`:
! Problem while computing `results = list(do.call(td, func_parm_list))`.
i The error occurred in group 1: n = 500, .mean = -1, .sd = 1, sim = 1.
Caused by error in `tidy_normal()`:
! unused arguments (n = c(500, 500, 500), sim = c(1, 1, 1))
Run `rlang::last_error()` to see where the error occurred.
Since I do not know what distribution the user is going to enter I wanted this function to be dynamic and use do.call instead of making an explicit rlang::call2 for each possibility.
I am not sure how to proceed from here as everything is failing, I assume because my do.call is wrong.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
