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
How to Save a Data Frame in a Txt or Excel File Separated by Columns
Is There a Fast Parser for Date
Why Is R Dplyr::Mutate Inconsistent with Custom Functions
Adding Shade to R Lineplot Denotes Standard Error
Mathematical Expression in Axis Label
How to Merge Multiple Data.Frames and Sum and Average Columns at the Same Time in R
Percentage of Overlap Between Polygons
Remove Zombie Processes Using Parallel Package
Plot Only One Side/Half of the Violin Plot
Roracle Not Working in R Studio
Why Does ".." Work to Pass Column Names in a Character Vector Variable
Can You More Clearly Explain Lazy Evaluation in R Function Operators
Ggplot2: Dashed Line in Legend
Running an R Script Using a Windows Shortcut
Compute Only Diagonals of Matrix Multiplication in R
How to Use an R Script from Github
Fastest Way to Read Large Excel Xlsx Files? to Parallelize or Not