Specify Function Parameters in Do.Call

Specify function parameters in do.call

You can add it as a named value to the existing list with c() which returns another list:

do.call(merge.xts, c( lapply(list.of.tickers, Yahoo.Fetch), all=FALSE ))

Or wrap the parameter in with an anonymous helper function:

do.call( function(x) merge.xts(x, all=FALSE), 
lapply(list.of.tickers, Yahoo.Fetch))

How to pass extra argument to the function argument of do.call in R

do.call(rbind.data.frame, c(list(iris), list(iris), stringsAsFactors=FALSE))

would have been my answer, if it wasn't for the fact that rbind does not know what to do with stringsAsFactors (but cbind.data.frame would).

The output of strsplit is presumably a list of vectors, in which case rbind creates a matrix. You can specify stringsAsFactors when converting this matrix to a data.frame,

data.frame(do.call(rbind, list(1:10, letters[1:10])), stringsAsFactors=FALSE)

How to add more arguments of a function in do.call?

consider this list of plots,

library(ggplot2)
library(gridExtra)
pl = replicate(5, qplot(1,1), simplify = FALSE)

you can combine it with a list of options to be passed to do.call,

do.call(grid.arrange, c(pl, list(ncol=5, main="title")))

how to pass optional arguments to function inside do.call

You can do do.call(paste, c(df, sep="_purchase_")), but maybe apply(df, 1, paste, collapse="_purchase_") is more straightforward.

Use do.call to run a function with a given list of parameters by the end user

The function parameter names should match with the column names of 'df' i.e. if we look at the output of 'df' inside the function

> df
# A tibble: 3 × 4
n .mean .sd sim
<int> <dbl> <dbl> <int>
1 50 -1 1 1
2 50 0 1 1
3 50 1 1 1

and the arguments of the tidynormal are

> formalArgs(tidy_normal)
[1] ".n" ".mean" ".sd" ".num_sims"

In the below code, the column names is changed to match the formalArgs as well as make use pmap to apply the function rowwise (which would be faster than rowwise)

...
names(df) <- formalArgs(td)
...
dff <- df %>% mutate(result = purrr::pmap(cur_data(), match.fun(td)))
...

We may have to change the function to

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)

names(df) <- formalArgs(td)
# Run call on the grouped df ----
#dff <- df %>%
# dplyr::rowwise() %>%
# dplyr::mutate(results = list(do.call(td, func_parm_list))) # fails here

dff <- df %>% mutate(results = purrr::pmap(cur_data(), match.fun(td)))

#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)

}

-testing

> out <- tidy_multi_dist(
+ .tidy_dist = "tidy_normal",
+ .param_list = list(
+ .n = 50,
+ .mean = c(-1, 0, 1),
+ .sd = 1,
+ .num_sims = 1)
+ )
> out
# A tibble: 150 × 8
sim_number dist_name x y dx dy p q
<fct> <fct> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 Gaussian c(-1, 1) 1 -0.879 -4.90 0.000211 0 -Inf
2 1 Gaussian c(-1, 1) 2 -1.70 -4.74 0.000585 0 -3.05
3 1 Gaussian c(-1, 1) 3 -1.72 -4.59 0.00142 0 -2.74
4 1 Gaussian c(-1, 1) 4 -0.577 -4.43 0.00306 0 -2.54
5 1 Gaussian c(-1, 1) 5 -1.87 -4.28 0.00583 0 -2.39
6 1 Gaussian c(-1, 1) 6 -0.779 -4.13 0.00990 0 -2.27
7 1 Gaussian c(-1, 1) 7 0.342 -3.97 0.0151 5.73e-300 -2.16
8 1 Gaussian c(-1, 1) 8 -2.28 -3.82 0.0212 1.12e-268 -2.07
9 1 Gaussian c(-1, 1) 9 -0.875 -3.66 0.0278 4.06e-239 -1.98
10 1 Gaussian c(-1, 1) 10 -1.77 -3.51 0.0350 2.70e-211 -1.90
# … with 140 more rows

> str(out)
tibble [150 × 8] (S3: tbl_df/tbl/data.frame)
$ sim_number: Factor w/ 1 level "1": 1 1 1 1 1 1 1 1 1 1 ...
$ dist_name : Factor w/ 3 levels "Gaussian c(-1, 1)",..: 1 1 1 1 1 1 1 1 1 1 ...
$ x : int [1:150] 1 2 3 4 5 6 7 8 9 10 ...
$ y : num [1:150] -1.901 -3.809 -1.186 -2.821 -0.666 ...
$ dx : num [1:150] -5.08 -4.93 -4.78 -4.63 -4.48 ...
$ dy : num [1:150] 0.000212 0.000573 0.001367 0.002882 0.005368 ...
$ p : num [1:150] 0 0 0 0 0 ...
$ q : num [1:150] -Inf -3.05 -2.74 -2.54 -2.39 ...
- attr(*, "all")=List of 10
..$ class : chr [1:3] "tbl_df" "tbl" "data.frame"
..$ row.names : int [1:50] 1 2 3 4 5 6 7 8 9 10 ...
..$ names : chr [1:7] "sim_number" "x" "y" "dx" ...
..$ .mean : num -1
..$ .sd : num 1
..$ .n : int 50
..$ .num_sims : int 1
..$ tibble_type: chr "tidy_gaussian"
..$ ps : num [1:50] -50 -48 -46 -44 -42 -40 -38 -36 -34 -32 ...
..$ qs : num [1:50] 0 0.0204 0.0408 0.0612 0.0816 ...
- attr(*, "tbl")= chr "tidy_multi_tibble"

Double colon operator to specify function in do.call

According to the documentation the what arg of do.call will take either a function or a non-empty character string naming the function to be called.

If you try implementing the double colon without the quotes it works:

> do.call(base::sum, list(1,2))
[1] 3

So while there is a function named sum in the package base, you can't name the function by also specifying the package. Instead, just remove the quotes.

Passing arguments to a function which is called by another function by its name in R

Assuming the inputs fun1, x, fun2 and args shown below the last line runs fun1.

fun1 <- function(x, fn, ...) fn(x) + fn(...)
x <- 3:4
fun2 <- sum
args <- list(1, 2)

do.call("fun1", c(list(x, fun2), args))
## [1] 10

do.call([...) function in R

Along with @thelatemail great comment, you can also get more information from the help page help('[') which reads

indexing by [ is similar to atomic vectors and selects a list of the specified element(s)

and from the help to function do.call we read

do.call constructs and executes a function call from a name or a function and a list of arguments to be passed to it.

This line is calling the [ function with the list argument dcargs (named because they are do.call arguments). Since the elements of dcargs are indices of the table, what this line is doing is referencing the relevant indices of the list object, contained in [[2]] and [[3]], which it is going to index.

In short, do.call("[",dcargs) indexes the no and yes rows and the no and yes columns of dcargs[[1]].

Passing character and data.frame arguments to a function using do.call()

do.call expects its first argument to be the 'name' of the function. Usually it works if this is entered as an R symbol (an expression without quotes) or expressed as a single element character value. In this case cfa is a wrapper for lavaan and the function name is converted to a list element named 'model.type' which succeeds when it is a character value but not when it is an R symbol-name of a function.

> do.call('cfa',args)
lavaan (0.5-15) converged normally after 56 iterations

Number of observations per group
0 50
1 50

Estimator ML
Minimum Function Test Statistic 0.000
Degrees of freedom 0
P-value (Chi-square) 0.000

Chi-square for each group:

0 0.000
1 0.000


Related Topics



Leave a reply



Submit