|Hello,
Given a function with several arguments, I would like to perform an
lapply (or equivalent) while holding one or more arguments fixed to some
common value, and I would like to do it in as elegant a fashion as
possible, without resorting to wrapping a separate wrapper for the
function if possible. Moreover I would also like it to work in cases
where one or more arguments to the original function has a default binding.
|
|# Here is an example; the original function|||
|||f <- function(w, y, z){ w + y + z }|||
||||
|||# common value I would like y to take|||
|||Y <- 5|||
||||
|||# I have a list of arguments for the lapply()|||
|||mylist <- list(one = list(w = 1, z = 2),|||
||| two = list(w = 3, z = 4)|||
||| )|||
||||
|||# one way to do it involves a custom wrapper||; I do not like
this method|
|||ret <- lapply(FUN = function(x,...) f(w = x$w, z = x$z, ...),|||
||| X = mylist,|||
||| y = Y|||
||| )|||
||||
|||# another way|||
|||ret <- lapply(FUN = with.default,|||
||| X = mylist,|||
||| expr = f(w, y = Y, z)|||
||| )|||
||||
|||# yet another way|||
|||ret <- lapply(FUN = eval,|||
||| X = mylist,|||
||| expr = substitute(f(w, y = Y, z))|||
||| )|||
||||
|||# now, the part I'm stuck on is for a version of f where z has a
default||binding|
|||f2 <- function(w, y, z = 0){ w + y + z }|||
||||
|||# the same as mylist, but now z is optional|||
|||mylist2 <- list(one = list(w = 1),|||
||| two = list(w = 3, z = 4)|||
||| )|||
||||
|||# undesired result||(first element has length 0)|
|||ret2 <- lapply(FUN = function(x,...) f2(w = x$w, z = x$z, ...),|||
||| X = mylist2,|||
||| y = Y|||
||| )|||
||||
|||# errors out ('z' not found)|||
|||ret2 <- lapply(FUN = with.default,|||
||| X = mylist2,|||
||| expr = f2(w, y = Y, z)|||
||| )|||
||||
|||# errors out again|||
|||ret2 <- lapply(FUN = eval,|||
||| X = mylist2,|||
||| expr = substitute(f2(w, y = Y, z))|||
||| )||
||
||# not quite...||
||ret2 <- lapply(FUN = gtools::defmacro(y = Y, expr = f2(w, y = Y,
z)),||
|| X = mylist2||
|| )|
||
|It seems like there are many ways to skin this cat; open to any and all
guidance others care to offer. |||
|Regards,
Ben
|
Apologies; resending in plain text...
Given a function with several arguments, I would like to perform an
lapply (or equivalent) while holding one or more arguments fixed to some
common value, and I would like to do it in as elegant a fashion as
possible, without resorting to wrapping a separate wrapper for the
function if possible. Moreover I would also like it to work in cases
where one or more arguments to the original function has a default binding.
# Here is an example; the original function
f <- function(w, y, z){ w + y + z }
# common value I would like y to take
Y <- 5
# I have a list of arguments for the lapply()
mylist <- list(one = list(w = 1, z = 2),
two = list(w = 3, z = 4)
)
# one way to do it involves a custom wrapper; I do not like this method
ret <- lapply(FUN = function(x,...) f(w = x$w, z = x$z, ...),
X = mylist,
y = Y
)
# another way
ret <- lapply(FUN = with.default,
X = mylist,
expr = f(w, y = Y, z)
)
# yet another way
ret <- lapply(FUN = eval,
X = mylist,
expr = substitute(f(w, y = Y, z))
)
# now, the part I'm stuck on is for a version of f where z has a
default binding
f2 <- function(w, y, z = 0){ w + y + z }
# the same as mylist, but now z is optional
mylist2 <- list(one = list(w = 1),
two = list(w = 3, z = 4)
)
# undesired result (first element has length 0)
ret2 <- lapply(FUN = function(x,...) f2(w = x$w, z = x$z, ...),
X = mylist2,
y = Y
)
# errors out ('z' not found)
ret2 <- lapply(FUN = with.default,
X = mylist2,
expr = f2(w, y = Y, z)
)
# errors out again
ret2 <- lapply(FUN = eval,
X = mylist2,
expr = substitute(f2(w, y = Y, z))
)
# not quite...
ret2 <- lapply(FUN = gtools::defmacro(y = Y, expr = f2(w, y = Y, z)),
X = mylist2
)
It seems like there are many ways to skin this cat; open to any and all
guidance others care to offer.
Regards,
Ben
One way is to use the do.call function. For example:
ret2 <- lapply(X=mylist2,
FUN=do.call,
what=function(...) f2(y=Y, ...))
Best,
Nello
-----Original Message-----
Date: Tue, 12 Mar 2013 22:37:52 -0400
From: Benjamin Tyner <btyner at gmail.com>
To: r-help at r-project.org
Subject: Re: [R] holding argument(s) fixed within lapply
Message-ID: <513FE680.2070404 at gmail.com>
Content-Type: text/plain; charset="iso-8859-1"
Apologies; resending in plain text...
Given a function with several arguments, I would like to perform an
lapply (or equivalent) while holding one or more arguments fixed to some
common value, and I would like to do it in as elegant a fashion as
possible, without resorting to wrapping a separate wrapper for the
function if possible. Moreover I would also like it to work in cases
where one or more arguments to the original function has a default
binding.
# Here is an example; the original function
f <- function(w, y, z){ w + y + z }
# common value I would like y to take
Y <- 5
# I have a list of arguments for the lapply()
mylist <- list(one = list(w = 1, z = 2),
two = list(w = 3, z = 4)
)
# one way to do it involves a custom wrapper; I do not like this
method
ret <- lapply(FUN = function(x,...) f(w = x$w, z = x$z, ...),
X = mylist,
y = Y
)
# another way
ret <- lapply(FUN = with.default,
X = mylist,
expr = f(w, y = Y, z)
)
# yet another way
ret <- lapply(FUN = eval,
X = mylist,
expr = substitute(f(w, y = Y, z))
)
# now, the part I'm stuck on is for a version of f where z has a
default binding
f2 <- function(w, y, z = 0){ w + y + z }
# the same as mylist, but now z is optional
mylist2 <- list(one = list(w = 1),
two = list(w = 3, z = 4)
)
# undesired result (first element has length 0)
ret2 <- lapply(FUN = function(x,...) f2(w = x$w, z = x$z, ....),
X = mylist2,
y = Y
)
# errors out ('z' not found)
ret2 <- lapply(FUN = with.default,
X = mylist2,
expr = f2(w, y = Y, z)
)
# errors out again
ret2 <- lapply(FUN = eval,
X = mylist2,
expr = substitute(f2(w, y = Y, z))
)
# not quite...
ret2 <- lapply(FUN = gtools::defmacro(y = Y, expr = f2(w, y = Y,
z)),
X = mylist2
)
It seems like there are many ways to skin this cat; open to any and all
guidance others care to offer.
Regards,
Ben