Hi,
I have a problem that I'm finding a bit tricky. I'm trying to use
mapply and assign to generate curried functions. For example, if I
have the function divide
divide <- function(x, y) {
x / y
}
And I want the end result to be functionally equivalent to:
half <- function(x) divide(x, 2)
third <- function(x) divide(x, 3)
quarter <- function(x) divide(x, 4)
But I want to do it using mapply and assign:
mapply(assign,
c("half", "third", "quarter"),
lapply(2:4, function(i) {function(x) divide(x, i)}),
pos = 1)
The problem is in the third line. I end up with 3 functions that are
all functionally equivalent to quarter(). Any suggestions on how to
get this to work properly.
Thanks.
James
On 3/12/2012 10:47 AM, J Toll wrote:> Hi, > > I have a problem that I'm finding a bit tricky. I'm trying to use > mapply and assign to generate curried functions. For example, if I > have the function divide > > divide<- function(x, y) { > x / y > } > > And I want the end result to be functionally equivalent to: > half<- function(x) divide(x, 2) > third<- function(x) divide(x, 3) > quarter<- function(x) divide(x, 4) > > But I want to do it using mapply and assign: > mapply(assign, > c("half", "third", "quarter"), > lapply(2:4, function(i) {function(x) divide(x, i)}), > pos = 1)The problem is with lazy argument evaluation/promises. i will be the last value of i (in this case 4) for all instances. You can change that. mapply(assign, c("half", "third", "quarter"), lapply(2:4, function(i) {force(i); function(x) divide(x, i)}), pos = 1) Note the inclusion of the force function. This gives expected results. > half(12) [1] 6 > third(12) [1] 4 > quarter(12) [1] 3> The problem is in the third line. I end up with 3 functions that are > all functionally equivalent to quarter(). Any suggestions on how to > get this to work properly. > > Thanks. > > > James >-- Brian S. Diggs, PhD Senior Research Associate, Department of Surgery Oregon Health & Science University
I think that adding a force(i) to your inner function should fix things up.
> z <- mapply(assign,
+ c("half", "third", "quarter"),
+ lapply(2:4, function(i) {
+ force(i)
+ function(x) divide(x, i)}),
+ pos = 1)
> half(10)
[1] 5
> third(10)
[1] 3.333333
> quarter(10)
[1] 2.5
Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at
r-project.org] On Behalf
> Of J Toll
> Sent: Monday, March 12, 2012 10:47 AM
> To: r-help
> Subject: [R] mapply & assign to generate functions
>
> Hi,
>
> I have a problem that I'm finding a bit tricky. I'm trying to use
> mapply and assign to generate curried functions. For example, if I
> have the function divide
>
> divide <- function(x, y) {
> x / y
> }
>
> And I want the end result to be functionally equivalent to:
> half <- function(x) divide(x, 2)
> third <- function(x) divide(x, 3)
> quarter <- function(x) divide(x, 4)
>
> But I want to do it using mapply and assign:
> mapply(assign,
> c("half", "third", "quarter"),
> lapply(2:4, function(i) {function(x) divide(x, i)}),
> pos = 1)
>
> The problem is in the third line. I end up with 3 functions that are
> all functionally equivalent to quarter(). Any suggestions on how to
> get this to work properly.
>
> Thanks.
>
>
> James
>
> ______________________________________________
> 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.