3

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.

WEVERETT
  • 87
  • 4
  • https://stackoverflow.com/questions/35823500/sorting-arguments-from-to-pass-them-only-to-functions-they-are-designed-to - is this of any help? – Vasily A Oct 29 '20 at 08:54
  • So although i was able to use the approach i still encountered the issue where it was unable to locate the n_max object. i was able to resolve the default_local() issue by loading the readr package with library(), but still encountered the missing n_max even after calling library(readxl). – WEVERETT Oct 31 '20 at 21:50

0 Answers0