Home > Back-end >  R Function Writing (Additional Arguments ...), passing to another function
R Function Writing (Additional Arguments ...), passing to another function

Time:01-25

I am writing on functions for my package, and have trouble in passing additional arguments with the ...
I have a "background" function, in the MRE from below I called it (change_font()), which takes e.g. in the example 2 arguments (fontsize and font).

Now I wrote a second function, called test()in the example, and would like it to have the option (with ...) to pass aditional arguments that should be passed to change_font().

Problem

It works with change_font(...) from inside test() as long as the ... only contains arguments used in the change_font function. I tried converting ... in a list and filter it for the arguments in the change_font() function which did not work.

Is there a convient way (inside the test function) to just select the arguments needed for change_font from the ... argument?

MRE

change_font <- function(fontsize = 12, font = "Times New Roman") {
  print(paste("Font is set to:", font))
  print(paste("Fontsize is set to:", fontsize))
}

test <- function(a = "ba", ...) {
  # change_font(...)
  # Works when only useable parameters are passed
  #    - However Fails when non-arguments from change_font are passed, e.g. test2 = 42
  
  # DID notwork
  # print(typeof(...))
  # print(class(...))
  
  
  # Trying to filter unused additional args
  additional_args <- list(...)[c("font","fontsize")]
  print(additional_args)
  # Filtering works fine. List only contains desired arguments
  change_font(additional_args)



  # if (hasArg(fontsize)) fontsize <- additional_args[["fontsize"]]
  # print(hasArg(font))
  # if (hasArg(font)) font = additional_args[["font"]]
  # # Try 2
  # change_font(
  #   font = font,
  #   fontsize = fontsize
  #
  # )
}

change_font()
#> [1] "Font is set to: Times New Roman"
#> [1] "Fontsize is set to: 12"
test(font = "ABC", fontsize = 111)
#> $font
#> [1] "ABC"
#> 
#> $fontsize
#> [1] 111
#> 
#> [1] "Font is set to: Times New Roman"
#> [1] "Fontsize is set to: ABC" "Fontsize is set to: 111"
test(font = "ABC", fontsize = 111, test2 = 42)
#> $font
#> [1] "ABC"
#> 
#> $fontsize
#> [1] 111
#> 
#> [1] "Font is set to: Times New Roman"
#> [1] "Fontsize is set to: ABC" "Fontsize is set to: 111"

Created on 2022-01-24 by the reprex package (v2.0.1)

CodePudding user response:

The best way to do this is to have dots as a parameter in change_font that are just ignored inside the body of the function.

Compare a minimal example where change_fonts doesn't have dots as a parameter:

change_font <- function(fontsize = 12, font = "Times New Roman") {

  print(paste("Font is set to:", font))
  print(paste("Fontsize is set to:", fontsize))
}
 

test <- function(a = "ab", ...) {

  change_font(...)
}

This results in an error if we pass an unrecognised parameter to test:

test(fontsize = 14, color = "red")
#> Error in change_font(...): unused argument (color = "red")

But look what happens when we include dots as a parameter in change_font:

change_font <- function(fontsize = 12, font = "Times New Roman", ...) {

  print(paste("Font is set to:", font))
  print(paste("Fontsize is set to:", fontsize))
}

test(fontsize = 14, color = "red")
#> [1] "Font is set to: Times New Roman"
#> [1] "Fontsize is set to: 14"

What's happening here is that in both cases color = "red" is being passed as a parameter to change_font, but in the second example, rather than getting the error that the color argument is unrecognised, it is interpreted as one of the "dots parameters", so doesn't trigger an error.

This is a very commonly used tactic in R.

Created on 2022-01-24 by the reprex package (v2.0.1)

  •  Tags:  
  • Related