简体   繁体   中英

Passing default arguments through nested functions in R

I have a general question about passing default arguments through nested functions in R. My example is (obviously) a great simplification of what I actually want to do, but I've had the problem other times so I'm looking for a general solution.

Basically I have three functions, and want some elements to have a default in all three. These functions are called within each other, but sometime called individually (ie foo1 calls foo2 , and foo2 calls foo3 , but sometimes I call just foo3 or foo2 ).

Edited to clarify: I am looking for a way to pass wd (and in my real problem) a few other variables through from the level of function that is called, without having to write them out in every function call. That is I want to set the default wd at all levels. To avoid naming them all different things which is confusing if you want to individually call the functions I tried having wd = wd in the function call of each (aiming to access the wd from the function it is calling. This gives promise already under evaluation: recursive default argument reference or earlier problems? . Is there a better way to pass the argument through so that when called within another function it passing the argument on?

My first example works shows working code, however every time I call the other functions within one I have to specify that wd = wd , which when it is a number of arguments, and I am calling the functions multiple times/within ddply makes the script cumbersome to work with.

The second example is what I was hoping for, where wd is by default set to wd in the environment it was called from but this is obviously not allowed the error occurs. What's the best approach to passing the argument without continually having to assign it?

Edit: I have looked at the answer to promise already under evaluation: recursive default argument reference or earlier problems? and I'm aware this is a possible work-around (its how I am currently running the script), but I was really hoping to have the same names for arguments of each function so that when they are called individually it is quick and easy to remember the argument names.

Example 1: works okay but no defaults set.

foo1 <- function(x, wd, reps){

  filename = paste0("Event", x)
  myString <- foo2(file = filename, wd = wd)
  rep(myString, reps)
}

foo2 <- function(file,wd){
  filePath <- file.path(wd,file)
  foo3(Path = filePath, wd = wd)
}

foo3 <- function(Path, wd){
  paste("Absolute File path is:", Path, "Current working Dir is:", wd)
}

foo1(1, wd = "c:/temp", 2)
foo2("C:/temp/otherfilename")

Example 2:

foo2 <- function(file,wd){
  filePath <- file.path(wd,file)
  foo3(Path = filePath)
}

foo3 <- function(Path, wd=wd){
  paste("Absolute File path is:", Path, "Current working Dir is:", wd)
}
foo1(1, wd = "c:/temp", 2)
> Error in paste("Absolute File path is:", Path, "Current working Dir is:",  : 
         promise already under evaluation: recursive default argument reference or earlier problems? 

I think you should not try to re-use the same name across different environments. Building off a possibly duplicate question at promise already under evaluation: recursive default argument reference or earlier problems? and some explanation from http://adv-r.had.co.nz/Environments.html#function-envs :

Why not use a separate name in each function, like this:

foo1 <- function(x, wd. = wd, reps){
  filename = paste0("Event", x)
  myString <- foo2(file = filename, wd.. = wd.)
  rep(myString, reps)
}

foo2 <- function(file, wd.. = wd){
  filePath <- file.path(wd.., file)
  foo3(Path = filePath)
}

foo3 <- function(Path, wd... = wd){
  paste("Absolute File path is:", Path, "Current working Dir is:", wd...)
}

EDIT in response to comments discussion. The code below might better accomplish your intent and works with your test calls foo1(1, wd = "c:/temp", 2) and foo2("C:/temp/otherfilename") :

foo1 <- function(x, ..., reps){
  filename = paste0("Event", x)
  myString <- foo2(file = filename, wd = wd)
  rep(myString, reps)
}

foo2 <- function(file, ...){
      filePath <- file.path(wd, file)
  foo3(Path = filePath)
}

foo3 <- function(Path, ...){
  paste("Absolute File path is:", Path, "Current working Dir is:", wd)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM