Re: [R] Help with workaround for: Function '`[`' is not in thederivatives table

From: <Bill.Venables_at_csiro.au>
Date: Tue 15 Aug 2006 - 16:57:40 EST


Earl F. Glynn asks:
> -----Original Message-----
> From: r-help-bounces@stat.math.ethz.ch
[mailto:r-help-bounces@stat.math.ethz.ch] On Behalf Of Earl F. Glynn
> Sent: Tuesday, 15 August 2006 8:44 AM
> To: r-help@stat.math.ethz.ch
> Subject: [R] Help with workaround for: Function '`[`' is not in
thederivatives table
>
> # This works fine:
> > a <- 1
> > b <- 2

> > c <- 3
> > E <- expression(a * exp(b*X) + c)
> > X <- c(0.5, 1.0, 2.0)
> > eval(E)
> [1] 5.718282 10.389056 57.598150
> > D(E, "b")
> a * (exp(b * X) * X)
> > eval(D(E, "b"))
> [1] 1.359141 7.389056 109.196300
>
> # But if (a,b,c) are replaced with (A[1], A[2], A[3]), how can I get a

> derivative using "D"?

It's well to note what "D" can differentiate with respect to. The second argument is, to quote the help page, a "character string giving the name of a variable..." 'A[1]' is a character string, but it is not the name of a variable. When parsed it becomes a call to the function, literally, `[`.

> > A <- c(1, 2, 3)
> > E <- expression(A[1] * exp(A[2]*X) + A[3])
> > X <- c(0.5, 1.0, 2.0)
> > eval(E)
> [1] 5.718282 10.389056 57.598150

No problem, because the evaluator does know how to evaluate `[`, along with everything else in this expr.

>
>
>
> # Why doesn't this work? Any workarounds?
> > D(E, "A[2]")
> Error in D(E, "A[2]") : Function '`[`' is not in the derivatives table

It fails because 'A[2]' is not a (character string giving the) name of a variable. I think the error message could be a bit more informative, but ... all you need to do is read he help page, really.

> If I want to have a long vector of coefficients, A, (perhaps
> dozens) how can I use "D" to compute partial derivatives?

Essentially you need to turn calls to '[' into names of variables, do the derivative business and then turn them back again. This is not easy to do in complete generality, but if you are only talking about singly subscripted arrays, you can get somewhere. Here is an outline of what I mean.

> Ident <- "([A-z][A-z0-9_.]*)"
> Subsc <- "([A-z][A-z0-9_.]*|[0-9]+)"
> patn <- paste(Ident, "\\[", Subsc, "\\]", sep = "")
> repl <- "\\1__\\2"
> E <- expression(A[1] * exp(A[2]*X) + A[3])
> Es <- deparse(E[[1]])
> Es
[1] "A[1] * exp(A[2] * X) + A[3]"
> Ess <- gsub(patn, repl, Es)
> Ess

[1] "A__1 * exp(A__2 * X) + A__3"
> Ex <- parse(text = Ess)[[1]]
> Ex

A__1 * exp(A__2 * X) + A__3

OK, the calls to `[` have been replaced by variables with two underscores in the middle. We hope this works - there is a strong assumption here on just how complicated your indices are, for example. We are assuming they are either identifiers (not using two successive underscores in their names) or numbers. If they are not, you need to get even craftier.

> Ex1 <- D(Ex, "A__2")
> Ex1

A__1 * (exp(A__2 * X) * X)
> Ex1s <- deparse(Ex1)
> Ex1s

[1] "A__1 * (exp(A__2 * X) * X)"
> pat1 <- paste(Ident, "__", Subsc, sep = "")
> rep1 <- "\\1\\[\\2\\]"
> Ex1ss <- gsub(pat1, rep1, Ex1s)
> Ex1ss

[1] "A[1] * (exp(A[2] * X) * X)"
> Ex2 <- parse(text = Ex1ss)[[1]]
> Ex2

A[1] * (exp(A[2] * X) * X)

Which is the required result. This is messy and gets messier if you are looking for some kind of generality, but you need to remember, R is not, and never will be, a replacement for Maple.

>
>
> Thanks for any help with this.

Best of luck in automating this, but the tools are there.

Bill Venables.



R-help@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 and provide commented, minimal, self-contained, reproducible code. Received on Tue Aug 15 17:02:59 2006

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.1.8, at Tue 15 Aug 2006 - 18:27:35 EST.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.