Skip to content

Pass vector as multiple parameters (as in python f(*x))

8 messages · Bert Gunter, Jeff Newmiller, Carlos Pita +2 more

#
Hi,

I want to know if it's possible to pass a vector v=c(x,y,...) to a
function f(x,y,...) so that each vector element corresponds to a
formal argument of the function. For python programmers: f(*v).

Specifically, what I'm trying to achieve is: given a list of
coordinates l=list(c(x1,y1,z1), c(x2,y2,z2),...) I would like to
obtain the corresponding elements in some array A (3-dim in this
case). That is: A[x1,y1,z1], A[x2,y2,z2],....

One way would be to transform l=list(c(x1,y1,z1), c(x2,y2,z2),...) to
l2=list(c(x1,x2,...),c(y1,y2,...),c(z1,z2,...)) and then (if this is
possible at all) execute the equivalent to A[*l2].

Another way would be to lapply function(xyz) { A[*xyz] } to each
coordinate vector in l. In any case I need the f(*v) equivalent.

Please take into account that, despite the 3-dim example, I need to
implement the above to accept n-dim vectors for arbitrary n, so
something like x<-xyz[1], y<-xyz[2], z<-xyz[3] wouldn't fit the bill.

Any other suggested solution would be appreciated.

Best regards
--
Carlos
#
Well, of course the answer is yes (it always is!). I'm just not sure
what the question is.

However, I believe you want something like

do.call(the_function, parameter_list).

?do.call  ## for details.

Note that if v is really a (named) vector, it can be converted to a
list via as.list().

Cheers,
Bert
On Fri, Jan 25, 2013 at 3:50 PM, Carlos Pita <carlosjosepita at gmail.com> wrote:

  
    
#
Your whole premise that the arguments of a function should be mappable to elements of a vector seems contrary to good R programming practice. Consider changing the called function's handling of arguments instead to accept the vector of data directly if a vector makes sense, or to a list if the arguments have a variety of types.
---------------------------------------------------------------------------
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.
Carlos Pita <carlosjosepita at gmail.com> wrote:

            
#
Thanks Bert, do.call is exactly what I was looking for. What in lisp
is apply and in python f(*v).
Jeff I didn't pretend to imply that the mapping should by always
possible. lists for positional arguments and named lists for named
arguments would do the trick most of the times. It's pretty common in
dynamic languages.

That said, the specific task I have in mind is to index an array of an
arbitrary dimension n by a list of length n vectors, each one
representing <x1,...,xn> coordinates.

For example, if n=2, the array is the matrix m, and the list of vectors is vs:

m=matrix(1:16,4)
vs = list(c(2,3),c(2,2),c(1,1))

Then do.call would allow me to index m as follows:

lapply(vs, function(v) { do.call(`[`, append(list(m), v)) })

Alternatively:

f = function (...) { m[...] }
lapply(vs, function(v) { do.call(f, as.list(v)) })

Of course, I could just do m[v[1],v[2]] in this case, but the point is
that the dimension n would be a parameter of my function, not a
constant.

But if you know of a better or more r-esque solution I would be very
glad to hear of it.

Best regards
--
Carlos


Best regards
--
Carlos

Consider changing the called function's handling of arguments instead
to accept the vector of data directly if a vector makes sense, or to a
list if the arguments have a variety of types.
#
s/by always/always be/

Sorry.
#
HI,

You could use ?Reduce() also in the second case:
lapply(vs,function(v){Reduce(f,as.list(v))})
#[[1]]
#[1] 10

#[[2]]
#[1] 6

#[[3]]
#[1] 1
A.K.





----- Original Message -----
From: Carlos Pita <carlosjosepita at gmail.com>
To: r-help at r-project.org
Cc: 
Sent: Friday, January 25, 2013 7:46 PM
Subject: Re: [R] Pass vector as multiple parameters (as in python f(*x))

Thanks Bert, do.call is exactly what I was looking for. What in lisp
is apply and in python f(*v).
Jeff I didn't pretend to imply that the mapping should by always
possible. lists for positional arguments and named lists for named
arguments would do the trick most of the times. It's pretty common in
dynamic languages.

That said, the specific task I have in mind is to index an array of an
arbitrary dimension n by a list of length n vectors, each one
representing <x1,...,xn> coordinates.

For example, if n=2, the array is the matrix m, and the list of vectors is vs:

m=matrix(1:16,4)
vs = list(c(2,3),c(2,2),c(1,1))

Then do.call would allow me to index m as follows:

lapply(vs, function(v) { do.call(`[`, append(list(m), v)) })

Alternatively:

f = function (...) { m[...] }
lapply(vs, function(v) { do.call(f, as.list(v)) })

Of course, I could just do m[v[1],v[2]] in this case, but the point is
that the dimension n would be a parameter of my function, not a
constant.

But if you know of a better or more r-esque solution I would be very
glad to hear of it.

Best regards
--
Carlos


Best regards
--
Carlos

Consider changing the called function's handling of arguments instead
to accept the vector of data directly if a vector makes sense, or to a
list if the arguments have a variety of types.
______________________________________________
R-help at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
#
How about (assuming the variables you defined):

ms <- matrix(unlist(vs), ncol=2,byrow=TRUE)
m[ms]

---------------------------------------------------------------------------
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.
Carlos Pita <carlosjosepita at gmail.com> wrote:

            
#
This an alternating way of doing it using a list if you know the
argument names in
the function definition i.e. ?formals and ?alist, But would change
the default values of the function. Probably not you wanted.
[1] 18
On 26 January 2013 01:46, Carlos Pita <carlosjosepita at gmail.com> wrote: