R: Building functions – using default settings that can be modified via the dot-dot-dot / three point argument

07Apr09

Before you read this post, please have a look at Enrique’s comment below. He pointed out that the built-in R function modifyList() already does what I wanted to describe in this post. Well, I live to learn :)

I was wondering how I could write a function that uses default settings but accepts a list to overwrite the default settings via the dot-dot-dot / three-point argument. Here comes my solution.

# building a function with a list of default settings
# that can be modified by an optional list passed
# via the dot-dot-dot / three point argument

###############################################################

myFunction <- function(...)
{
  print(hasArg(settings))
}

myFunction()
myFunction(settings=list(par1=8))

###############################################################

# now I define a default setting list

myFunction <- function(...)
{
  print(hasArg(settings))
  # define default settings
  settings = list(par1=10, par2=12)
  print(settings)
}

myFunction()
myFunction(settings=list(par1=8))

###############################################################

# as a next step I replace all the elements passed on to
# settings via the dot-dot-dot argument

myFunction <- function(...)
{
  # default settings
  settings = list(par1=10, par2=12)       
  # if settings argument is used
  if(hasArg(settings)){
      suppliedSettings <- list(...)$settings
      matching <- intersect(names(settings),
                            names(suppliedSettings))
      settings[matching] <- suppliedSettings[matching]
  }

  # function operations
  print(settings)
}

myFunction()
myFunction(settings=list(par1=8))

# Now the settings have changed.

###############################################################

# If now some settings are supplied that do not match they
# are simply not considered

myFunction(settings=list(par1=8, parX=6))
# For convenience I add a line to warn the user in case of not
# matching parameters

myFunction <- function(...)
{
  # default settings
  settings = list(par1=10, par2=12)
  # if settings is supplied
  if(hasArg(settings)){
      suppliedSettings <- list(...)$settings
      matching <- intersect(names(settings),
                            names(suppliedSettings))
      settings[matching] <- suppliedSettings[matching]
      notMatching <- setdiff(names(suppliedSettings),
                             names(settings))
      if(length(notMatching)!=0) warning(paste("The
            following arguments are ignored: ", notMatching))
  }

  # function operations
  print(settings)
}

###############################################################

myFunction(settings=list(par1=8, parX=6))
# now the user is warned when some arguments do not match

by Mark Heckmann, April, 2009
About these ads


4 Responses to “R: Building functions – using default settings that can be modified via the dot-dot-dot / three point argument”

  1. 1 Enrique

    Hi Mark,

    Have you tried “modifyList(settings, list(…)$settings)” ?

    Enrique

  2. 2 Byron

    Why not myFunction = function(…,par1=8,parX=6) ? Alternatively, you could pass in a settings object but have a second function that handles the processing for you, like the link function in glm.

  3. 3 markheckmann

    Hi Enrique,
    thanks for this hint. I did not know the function and it does more or less what my one does but in much betrter way. :) E.g. it works on all list levels due to its recursive structure.
    Thanks!

    Mark

  4. 4 markheckmann

    Hi Byron,
    I wanted to avoid passing default settings like in myFunction = function(…,par1=8,parX=6) explicitly as in my case it would be far too many. An option clearly would be to pass a settings object like e.g. the gpar object in grid graphics. But still I wanted to define a default settings object inside the function in case no settings object is provided. In case there is no gpar object the grid functions use the gpar default object. That was what I wanted to do, but it might be that there is an easier way?!
    Mark



Follow

Get every new post delivered to your Inbox.

Join 54 other followers

%d bloggers like this: