I have a (remarkably ugly!!) code snippet (below) that, given
two simple functions, f and g, generates
a list of new functions h_{k+1} = h_k * g, k= 1, ?, K. Surely, there are
vastly
better ways to do this. I don?t particularly care about the returned list,
I?d be happy to have the final h_K version of the function,
but I keep losing my way and running into the dreaded:
Error in h[[1]] : object of type 'closure' is not subsettable
or
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
Mainly I?d like to get rid of the horrible, horrible paste/parse/eval evils.
Admittedly
the f,g look a bit strange, so you may have to suspend disbelief to imagine that
there is
something more sensible lurking beneath this minimal (toy) example.
f <- function(u) function(x) u * x^2
g <- function(u) function(x) u * log(x)
set.seed(3)
a <- runif(5)
h <- list()
hit <- list()
h[[1]] <- f(a[1])
hit[[1]] <- f(a[1])
for(i in 2:5){
ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i],
")(x)")
h[[i]] <- eval(parse(text = ht))
hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
}
x <- 1:99/10
plot(x, h[[1]](x), type = "l")
for(i in 2:5)
lines(x, h[[i]](x), col = i)
Thanks,
Roger
Does this do what you want:
f <- function(u) function(x) u * x^2
g <- function(u) function(x) u * log(x)
set.seed(3)
a <- runif(5)
h <- list()
hit <- list()
h[[1]] <- f(a[1])
hit[[1]] <- f(a[1])
for(i in 2:5)h[[i]] <- eval(bquote(function(x).(h[[i-1]])(x) * g(a[i])(x)))
x <- 1:99/10
plot(x, h[[1]](x), type = "l")
for(i in 2:5){
i
lines(x, h[[i]](x), col = i)
}
Cheers,
Bert
Bert Gunter
"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
On Wed, Mar 2, 2016 at 8:47 AM, Roger Koenker <rkoenker at illinois.edu>
wrote:> I have a (remarkably ugly!!) code snippet (below) that, given
> two simple functions, f and g, generates
> a list of new functions h_{k+1} = h_k * g, k= 1, ?, K. Surely, there are
vastly
> better ways to do this. I don?t particularly care about the returned list,
> I?d be happy to have the final h_K version of the function,
> but I keep losing my way and running into the dreaded:
>
> Error in h[[1]] : object of type 'closure' is not subsettable
> or
> Error: evaluation nested too deeply: infinite recursion /
options(expressions=)?
>
> Mainly I?d like to get rid of the horrible, horrible paste/parse/eval
evils. Admittedly
> the f,g look a bit strange, so you may have to suspend disbelief to imagine
that there is
> something more sensible lurking beneath this minimal (toy) example.
>
> f <- function(u) function(x) u * x^2
> g <- function(u) function(x) u * log(x)
> set.seed(3)
> a <- runif(5)
> h <- list()
> hit <- list()
> h[[1]] <- f(a[1])
> hit[[1]] <- f(a[1])
> for(i in 2:5){
> ht <- paste("function(x) h[[", i-1, "]](x) *
g(", a[i], ")(x)")
> h[[i]] <- eval(parse(text = ht))
> hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
> }
> x <- 1:99/10
> plot(x, h[[1]](x), type = "l")
> for(i in 2:5)
> lines(x, h[[i]](x), col = i)
>
> Thanks,
> Roger
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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.
On 02/03/2016 11:47 AM, Roger Koenker wrote:> I have a (remarkably ugly!!) code snippet (below) that, given > two simple functions, f and g, generates > a list of new functions h_{k+1} = h_k * g, k= 1, ?, K. Surely, there are vastly > better ways to do this. I don?t particularly care about the returned list, > I?d be happy to have the final h_K version of the function, > but I keep losing my way and running into the dreaded: > > Error in h[[1]] : object of type 'closure' is not subsettable > or > Error: evaluation nested too deeply: infinite recursion / options(expressions=)? > > Mainly I?d like to get rid of the horrible, horrible paste/parse/eval evils. Admittedly > the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is > something more sensible lurking beneath this minimal (toy) example. > > f <- function(u) function(x) u * x^2 > g <- function(u) function(x) u * log(x) > set.seed(3) > a <- runif(5) > h <- list() > hit <- list() > h[[1]] <- f(a[1]) > hit[[1]] <- f(a[1]) > for(i in 2:5){ > ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)") > h[[i]] <- eval(parse(text = ht)) > hit[[i]] <- function(x) {force(i); return(h[[i]] (x))} > } > x <- 1:99/10 > plot(x, h[[1]](x), type = "l") > for(i in 2:5) > lines(x, h[[i]](x), col = i)I don't understand what "hit" is for, but something like this should do it: hlist <- function(maxk, f,g,a) { h <- list() h[[1]] <- f(a[1]) for (j in 2:maxk) { h[[j]] <- local({ k <- j function(x) { result <- h[[1]](x) for (i in 2:k) { result <- result*g(a[i])(x) } result } }) } h } f <- function(u) function(x) u * x^2 g <- function(u) function(x) u * log(x) set.seed(3) a <- runif(5) h <- hlist(5, f, g, a)
On 02.03.2016 18:47, Roger Koenker wrote:> I have a (remarkably ugly!!) code snippet (below) that, given > two simple functions, f and g, generates > a list of new functions h_{k+1} = h_k * g, k= 1, ?, K. Surely, there are vastly > better ways to do this. I don?t particularly care about the returned list, > I?d be happy to have the final h_K version of the function, > but I keep losing my way and running into the dreaded: > > Error in h[[1]] : object of type 'closure' is not subsettable > or > Error: evaluation nested too deeply: infinite recursion / options(expressions=)? > > Mainly I?d like to get rid of the horrible, horrible paste/parse/eval evils. Admittedly > the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is > something more sensible lurking beneath this minimal (toy) example. > > f <- function(u) function(x) u * x^2 > g <- function(u) function(x) u * log(x) > set.seed(3) > a <- runif(5) > h <- list() > hit <- list() > h[[1]] <- f(a[1]) > hit[[1]] <- f(a[1]) > for(i in 2:5){ > ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)") > h[[i]] <- eval(parse(text = ht)) > hit[[i]] <- function(x) {force(i); return(h[[i]] (x))} > } > x <- 1:99/10 > plot(x, h[[1]](x), type = "l") > for(i in 2:5) > lines(x, h[[i]](x), col = i)Here is my (ugly?) suggestion: f <- function(u) function(x) u * x^2 g <- function(u) function(x) u * log(x) set.seed(3) a <- runif(5) h <- f(a[1]) for (i in 2:5) { body(h) <- call("*", body(h), as.call(list(do.call("g", list(a[i])), quote(x)))) } -- Mikko Korpela Aalto University School of Science Department of Computer Science
This manufactures the functions without using eval by using substitute
to substitute i-1 and a[i] into an expression for the body which is
then assigned to the body of the function:
hh <- vector("list", 5)
hh[[1]] <- f(a[1])
for(i in 2:5) {
hh[[i]] <- hh[[1]]
body(hh[[i]]) <- substitute(hh[[iprev]](x) * g(ai)(x), list(iprev
= i-1, ai = a[i]))
}
all.equal(h[[5]](.5), hh[[5]](.5)) # test
## [1] TRUE
This uses quote to define the body of h[[i]] as a call object and then
substitutes in the values of i-1 and a[i] assigning the result to the
body of h[[i]].
h <- vector("list", 5)
h[[1]] <- f(a[1])
for(i in 2:5) {
h[[i]] <- h[[1]]
body(hh[[i]]) <- do.call(substitute,
list(quote(hh[[iprev]](x) *
g(ai)(x)),
list(iprev = i-1, ai = a[i])))
}
On Wed, Mar 2, 2016 at 11:47 AM, Roger Koenker <rkoenker at illinois.edu>
wrote:> I have a (remarkably ugly!!) code snippet (below) that, given
> two simple functions, f and g, generates
> a list of new functions h_{k+1} = h_k * g, k= 1, ?, K. Surely, there are
vastly
> better ways to do this. I don?t particularly care about the returned list,
> I?d be happy to have the final h_K version of the function,
> but I keep losing my way and running into the dreaded:
>
> Error in h[[1]] : object of type 'closure' is not subsettable
> or
> Error: evaluation nested too deeply: infinite recursion /
options(expressions=)?
>
> Mainly I?d like to get rid of the horrible, horrible paste/parse/eval
evils. Admittedly
> the f,g look a bit strange, so you may have to suspend disbelief to imagine
that there is
> something more sensible lurking beneath this minimal (toy) example.
>
> f <- function(u) function(x) u * x^2
> g <- function(u) function(x) u * log(x)
> set.seed(3)
> a <- runif(5)
> h <- list()
> hit <- list()
> h[[1]] <- f(a[1])
> hit[[1]] <- f(a[1])
> for(i in 2:5){
> ht <- paste("function(x) h[[", i-1, "]](x) *
g(", a[i], ")(x)")
> h[[i]] <- eval(parse(text = ht))
> hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
> }
> x <- 1:99/10
> plot(x, h[[1]](x), type = "l")
> for(i in 2:5)
> lines(x, h[[i]](x), col = i)
>
> Thanks,
> Roger
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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.
--
Statistics & Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com