Bill.Venables at csiro.au
2006-Aug-15 06:57 UTC
[R] Help with workaround for: Function '`[`' is not in thederivatives table
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 inthederivatives 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.598150No 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 tableIt 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]] > ExA__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") > Ex1A__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]] > Ex2A[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.