Antonio.Gasparrini at lshtm.ac.uk
2010-Dec-01 19:34 UTC
[R] default arguments and '...' in a function
Dear R-users, I'm trying to work out a way to set default values for arguments in a function which includes the optional argument '...'. In practice, I have a 'plot' method for a function which specifies different types of plots. Every different plot should have different default arguments (for example for 'col', 'ylim' etc), plus the argument '...' to leave further optional choices to the user. My problem is that I need to specify a large number of arguments in the usage (losing clarity), or alternatively leaving to the user the specification of an high number of argument (adding complexity). An example. Suppose I want to create a function f with arguments 'a', and '...'. Two more arguments 'b' and 'c' should be both set to 1 by default if the user don't include them in '...'. f <- function(a,...) { # set b <- 1 if b is not included in '...' # set c <- 1 if c is not included in '...' somefunction(a,b,c,...) } I found that internally the optional arguments are stored in list(...), but I haven't found a way to manage them, so the final call to somefunction() will include 'b' and 'c' twice if the user have included them in '...', and returns an error. Does anyone have some suggestion? Thanks for your time Antonio Gasparrini London School of Hygiene & Tropical Medicine Department of Social and Environmental Health Research 15-17 Tavistock Place, London WC1H 9SH, UK
Antonio, You need to compare the names of list(...) with the arguments you wish to check. Here's one way to do so (note that I replaced c with d, because c is a function): f <- function(a, ...) { argnames <- names(list(...)) # check whether b is an argument if(!("b" %in% argnames)) { b <- 1 } # check whether d is an argument if(!("d" %in% argnames)) { d <- 1 } # return NA for b and d if specified, but don't set a value list(a=a, b=ifelse(exists("b"), b, NA), d=ifelse(exists("d"), d, NA), args=list(...)) }> f(a=1)$a [1] 1 $b [1] 1 $d [1] 1 $args list()> f(a=1, b=2)$a [1] 1 $b [1] NA $d [1] 1 $args $args$b [1] 2> f(a=1, b=2, d=3)$a [1] 1 $b [1] NA $d [1] NA $args $args$b [1] 2 $args$d [1] 3 Sarah On Wed, Dec 1, 2010 at 2:34 PM, <Antonio.Gasparrini at lshtm.ac.uk> wrote:> Dear R-users, > > I'm trying to work out a way to set default values for arguments in a function which includes the optional argument '...'. > In practice, I have a 'plot' method for a function which specifies different types of plots. Every different plot should have different default arguments (for example for 'col', 'ylim' etc), plus the argument '...' to leave further optional choices to the user. > My problem is that I need to specify a large number of arguments in the usage (losing clarity), or alternatively leaving to the user the specification of an high number of argument (adding complexity). > > An example. > Suppose I want to create a function f with arguments 'a', and '...'. > Two more arguments 'b' and 'c' should be both set to 1 by default if the user don't include them in '...'. > > f <- function(a,...) { > ?# set b <- 1 if b is not included in '...' > ?# set c <- 1 if c is not included in '...' > ?somefunction(a,b,c,...) > } > > I found that internally the optional arguments are stored in list(...), but I haven't found a way to manage them, so the final call to somefunction() will include 'b' and 'c' twice if the user have included them in '...', and returns an error. > > Does anyone have some suggestion? > Thanks for your time > > Antonio Gasparrini > London School of Hygiene & Tropical Medicine > Department of Social and Environmental Health Research > 15-17 Tavistock Place, London WC1H 9SH, UK > > _______-- Sarah Goslee http://www.functionaldiversity.org
On Wed, Dec 1, 2010 at 2:34 PM, <Antonio.Gasparrini at lshtm.ac.uk> wrote:> Dear R-users, > > I'm trying to work out a way to set default values for arguments in a function which includes the optional argument '...'. > In practice, I have a 'plot' method for a function which specifies different types of plots. Every different plot should have different default arguments (for example for 'col', 'ylim' etc), plus the argument '...' to leave further optional choices to the user. > My problem is that I need to specify a large number of arguments in the usage (losing clarity), or alternatively leaving to the user the specification of an high number of argument (adding complexity). > > An example. > Suppose I want to create a function f with arguments 'a', and '...'. > Two more arguments 'b' and 'c' should be both set to 1 by default if the user don't include them in '...'. > > f <- function(a,...) { > ?# set b <- 1 if b is not included in '...' > ?# set c <- 1 if c is not included in '...' > ?somefunction(a,b,c,...) > } >Try using modifyList as shown: # simple function for illustration somefunction <- function(a, b, c) sprintf("a: %d, b: %d, c: %d", a, b, c) f <- function(a, ...) { L <- modifyList(list(b = 1, c = 1), list(a = a, ...)) do.call(somefunction, L) } f(5, c = 3) # "a: 5, b: 1, c: 3" -- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com