Skip to content

passing elements of named vector / named list to function

3 messages · Rainer M Krug, Jeff Newmiller

#
Hi

Following scenario: I have a function fun

--8<---------------cut here---------------start------------->8---
fun <- function(A, B, C, ...){paste(A, B, C, ...)}
--8<---------------cut here---------------end--------------->8---

and x defined as follow

--8<---------------cut here---------------start------------->8---
x <- 1:5
names(x) <- LETTERS[x]
--8<---------------cut here---------------end--------------->8---

now I want to pass the *elements* of x to fun as named arguments, i.e.

,----
| > fun(A=1, B=2, C=3, D=4, E=5)
| [1] "1 2 3 4 5"
`----

The below examples obviously do not work:

,----
| > fun(x)
| Error in paste(A, B, C, list(...)) :
|   argument "B" is missing, with no default
| > fun(unlist(x))
| Error in paste(A, B, C, list(...)) :
|   argument "B" is missing, with no default
`----

How can I extract from x the elements and pass them on to fun()?

I could easily change x to a list() if this would be easier.

--8<---------------cut here---------------start------------->8---
x <- list(A=1, B=2, C=3, D=4, E=5)
--8<---------------cut here---------------end--------------->8---

In my actual program, x can have different elements as well as fun -
this is decided programmatically.

Any suggestions how I can achieve this?

Thanks,

Rainer
#
It x is a list...

do.call(fun,x)

You should keep external data input away from this code construct to avoid intentional or unintentional misuse of your fun.

If your toy example were your actual usage I would suggest the collapse argument of paste.
---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<jdnewmil at dcn.davis.ca.us>        Basics: ##.#.       ##.#.  Live Go...
                                      Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...1k
--------------------------------------------------------------------------- 
Sent from my phone. Please excuse my brevity.
On January 15, 2015 6:25:43 AM PST, Rainer M Krug <Rainer at krugs.de> wrote:
#
Jeff Newmiller <jdnewmil at dcn.davis.ca.us> writes:
Thanks - works perfectly. Only one further question:

In my original usage, fun() is an S3 Generic Function and takes as the
first argument an object which obviously *must not be* expanded, while
the ... need to be extended.

--8<---------------cut here---------------start------------->8---
fun.obj <- function(x, ...) {
  y <- fun2(x)
  y$text <- paste(y$text, ..., collapse="|")
  return(y)
}
--8<---------------cut here---------------end--------------->8---

so

--8<---------------cut here---------------start------------->8---
do.call(fun, c(x, list(A=2, B=3))
--8<---------------cut here---------------end--------------->8---

obviously does not work.

So at the moment I am using a helper function:

--8<---------------cut here---------------start------------->8---
x <- AClassObjObject()
funhelp <- function(...) {fun(x, ...)}
do.call(funhelp, list(A=2, B=3))
--8<---------------cut here---------------end--------------->8---

which works but is not nice at all (as the x is from the environment
below). Is there a way of expand the ... but not the x?

Thanks,

Rainer