|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