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

Bill.Venables at csiro.au Bill.Venables at csiro.au
Tue Aug 15 08:57:40 CEST 2006


Earl F. Glynn asks: 
> -----Original Message-----
> From: r-help-bounces at stat.math.ethz.ch
[mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Earl F. Glynn
> Sent: Tuesday, 15 August 2006 8:44 AM
> To: r-help at 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.



More information about the R-help mailing list