So i have a wrapper function that contains a lot of sub functions. Rather than write out arguments for all the potential arguments for each sub functions in the wrapper. I want to use ... (dots) to allow them to pass through any number of arguments to change the behaviour of sub functions if necessary.
The problem is that several functions may wish to make use of different arguments ... and i keep getting unused argument errors.
So I've tried to use do.call and to update the formals outputs with matches from ... see below code for function
elipRead <- function( type, path, ...){
if(type == "csv"){
ar <- list(...)
args <- formals(readr::read_csv)
args$file <- path
args[which(names(args) %in% names(ar))] <- ar[na.omit(match(names(args), names(ar)))]
out <- do.call(readr::read_csv, args = args)
} else {
ar <- list(...)
args <- formals(readxl::read_xlsx)
args$path <- path
args[which(names(args) %in% names(ar))] <- ar[na.omit(match(names(args), names(ar)))]
out <- do.call(readxl::read_xlsx, args)
}
return(out)
}
However, despite checking the args list is updating correctly i still get errors
csv <-"csv_Filename.csv"
test1 <- elipRead("csv", paste0(getwd(),csv), sheet = "Sheet1" , col_names = FALSE)
# Error in default_locale() : could not find function "default_locale"
xlsx <-"xlsx_Filename.xlsx"
test2 <- elipRead("xlsx", paste0(getwd(),xlsx), sheet = "Sheet1", col_names = TRUE)
# Error: `guess_max` must be a positive integer
for the xlsx attempt the error is in the guess_max default where it cannot find n_max object. I assume this is to do with do.call envir and n_max not being in the parent environment. For the csv issue again its an issue of not being able to find the default_local() function.
Error in check_non_negative_integer(guess_max, "guess_max") :
object 'n_max' not found
6.
check_non_negative_integer(guess_max, "guess_max")
5.
check_guess_max(guess_max)
4.
read_excel_(path = path, sheet = sheet, range = range, col_names = col_names,
col_types = col_types, na = na, trim_ws = trim_ws, skip = skip,
n_max = n_max, guess_max = guess_max, progress = progress,
.name_repair = .name_repair, format = "xlsx")
3.
(function (path, sheet = NULL, range = NULL, col_names = TRUE,
col_types = NULL, na = "", trim_ws = TRUE, skip = 0, n_max = Inf,
guess_max = min(1000, n_max), progress = readxl_progress(),
.name_repair = "unique") ...
2.
do.call(readxl::read_xlsx, args)
1.
elipRead("xlsx", paste0(add, xlsx), sheet = "Sheet1", col_names = TRUE)
In the end there are three potential answers i'm hoping for:
1 recommendations of changes to my current code to ensure the do.call function works.
2 An alternative method for using ... to only pass the relevant arguments from the ... dots list to a function.
3 An completely different approach for passing arguments from a wrapper to internal functions.