Hi.
I'm having difficulty following the advice given in help(Recall).
Consider the two
following toy functions:
f1 <- function(n){
if(length(n)>1){return(sapply(n,f1))}
matrix(n,n,n)
}
f2 <- function(n){
if(length(n)>1){return(sapply(n,Recall))}
matrix(n,n,n)
}
f1() works as desired (that is, f(1:3), say, gives me a three element
list whose i-th element
is an i-by-i matrix whose elements are all i).
But f2() doesn't.
How do I modify either function to use Recall()? What exactly is
Recall() calling here?
--
Robin Hankin
Uncertainty Analyst
Southampton Oceanography Centre
European Way, Southampton SO14 3ZH, UK
tel 023-8059-7743
I doubt it's possible to use Recall inside a sapply like this. sapply
(and lapply) make a copy of the function (FUN <- match.fun(FUN)) before
passing it inside an internal function (rval <- .Internal(lapply(X,
FUN)). So, while I'm not precisely sure how Recall is coded up, I bet
that once it is copied inside of sapply (and lapply), it loses the
context from which it was called.
I can think of a couple ways around this. First, you could construct a
for loop instead of a sapply and use Recall. Second, you could replace
Recall by just asking R what the name of the calling function is and
pass that in to sapply. Something like this should work:
sapply(n, match.fun(sys.call()[[1]]))
HTH,
Robert
-----Original Message-----
From: Robin Hankin [mailto:r.hankin at soc.soton.ac.uk]
Sent: Wednesday, March 30, 2005 3:28 AM
To: R-help at stat.math.ethz.ch
Subject: [R] Recall() and sapply()
Hi.
I'm having difficulty following the advice given in help(Recall).
Consider the two
following toy functions:
f1 <- function(n){
if(length(n)>1){return(sapply(n,f1))}
matrix(n,n,n)
}
f2 <- function(n){
if(length(n)>1){return(sapply(n,Recall))}
matrix(n,n,n)
}
f1() works as desired (that is, f(1:3), say, gives me a three element
list whose i-th element
is an i-by-i matrix whose elements are all i).
But f2() doesn't.
How do I modify either function to use Recall()? What exactly is
Recall() calling here?
--
Robin Hankin
Uncertainty Analyst
Southampton Oceanography Centre
European Way, Southampton SO14 3ZH, UK
tel 023-8059-7743
______________________________________________
R-help at stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide!
http://www.R-project.org/posting-guide.html
I believe that the function that Recall executes is the
function in which Recall, itself, is evaluated -- not the
function in which Recall appears. In normal cases these are
the same but if you pass Recall to another function then
they are not the same. Here Recall is being passed to
sapply (which in turn is likely passing it to other
functions). Because of lazy evaluation Recall does not get
evaluated until it is found within sapply (or a function
called by it or called by one called by it, etc.) and at
that point its recalling the wrong function. AFAICS one
cannot pass Recall to another function.
You could rewrite the expression that uses sapply to use
iteration instead or you could do it as shown below.
In this example, the use of f2 within supply refers to
the inner f2 which does not change even if the name of
the outer f2 does.
f2 <- function(n) {
f2 <- function(n) if(length(n)>1) sapply(n,f2) else matrix(n,n,n)
f2(n)
}
f3 <- f2
f2(1:3)
f3(1:3) # gives same result
On Wed, 30 Mar 2005 09:28:08 +0100, Robin Hankin
<r.hankin at soc.soton.ac.uk> wrote:> Hi.
>
> I'm having difficulty following the advice given in help(Recall).
> Consider the two
> following toy functions:
>
> f1 <- function(n){
> if(length(n)>1){return(sapply(n,f1))}
> matrix(n,n,n)
> }
>
> f2 <- function(n){
> if(length(n)>1){return(sapply(n,Recall))}
> matrix(n,n,n)
> }
>
> f1() works as desired (that is, f(1:3), say, gives me a three element
> list whose i-th element
> is an i-by-i matrix whose elements are all i).
>
> But f2() doesn't.
>
> How do I modify either function to use Recall()? What exactly is
> Recall() calling here?
>
> --
> Robin Hankin
> Uncertainty Analyst
> Southampton Oceanography Centre
> European Way, Southampton SO14 3ZH, UK
> tel 023-8059-7743
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide!
http://www.R-project.org/posting-guide.html
>
On Wed, 30 Mar 2005, Robin Hankin wrote:> Hi. > > I'm having difficulty following the advice given in help(Recall). Consider > the two > following toy functions: > > > f1 <- function(n){ > if(length(n)>1){return(sapply(n,f1))} > matrix(n,n,n) > } > > f2 <- function(n){ > if(length(n)>1){return(sapply(n,Recall))} > matrix(n,n,n) > } > > > f1() works as desired (that is, f(1:3), say, gives me a three element list > whose i-th element > is an i-by-i matrix whose elements are all i). > > But f2() doesn't. > > How do I modify either function to use Recall()? What exactly is Recall() > calling here? >You can't use Recall here. I thought this was explicitly documented, but it turns out that it isn't, an omission I will fix. You don't need Recall, because R can easily have recursive functions without it (unlike S) - as you show in f1, the function can call itself - the problem with f1 is that it stops working if you change the name, but ?local shows how to get around this. This is probably the best way to implement recursion. - You can even implement Y, the "appplicative-order fixed point operator" to create anonymous recursive functions a la lambda calculus. -thomas