4

在 R 中,我想要一种方法来获取公式右侧的符号导数,其中可能包括交互项、平方项等。

例如,我希望能够对以下两个 [edit:three] 公式中的每一个求得右手边关于 x 的导数:

y~x+I(x^2)

y~x:z

编辑:y~x*z

我想要一个函数,当输入上述三个公式中的每一个时,分别返回 1+2x、z 和 1+z。

我尝试了以下方法:

f1<-y~x+I(x^2)
deriv(f1,"x")
## Error in deriv.formula(f1, "x") : Function 'I' is not in the derivatives table

f2<-y~x:z
deriv(f2,"x")
## Error in deriv.formula(f2, "x") : Function '`:`' is not in the derivatives table

有什么方法可以强制 R 将 I(x^2)(或类似地,I(x*z) 等)识别为 x^2(分别为 x*z),x:z 识别为 x*z(在数学意义上)和 x*z(在公式意义上)作为 x+z+x*z(在数学意义上)用于计算导数?

其次,有没有办法从 deriv() 获取输出并将其重塑为看起来像公式的右侧?特别是,我知道 D() 将缓解这个问题并以我想要的形式生成输出(尽管 D() 不能将公式作为输入处理),但是如果我想对多个变量进行导数怎么办?我可以通过对每个我想对其进行导数的变量反复应用 D() 来解决这个问题,但是最好简单地输入所有这些变量的字符串并接收适合放置的输出在公式的右边。

谢谢!

4

2 回答 2

2

If you have a formula expression you can work with it using substitute():

substitute( x~x:z+x:y , list(`:`=as.name("*") ) )
x ~ x * z + x * y

And this will let you pass an expression object to substitute with it first being evaluated (which would otherwise not happen since substitute does not evaluate its first argument):

form1 <- expression(x ~ x : z + x : y)
rm(form2)
form2 <- do.call('substitute' , list(form , list(`:`=as.name("*") ) ))
form2
# expression(x ~ x * z + x * y)

This shows how to "reshape" the RHS so that y ~ x:z is handled like ~ x*z by extracting the RHS from its list structure where the tilde operator is being treated as a function and the LHS is the second element in (~ , <LHS>, <RHS>):

 f2<-y~x:z
 substar <- function(form) { 
            do.call('substitute' , list(form , list(`:`=as.name("*") ) )) }
 f3 <- substar(f2)
 deriv(f3[[3]],"x")
 #----------------------
expression({
    .value <- x * z
    .grad <- array(0, c(length(.value), 1L), list(NULL, c("x")))
    .grad[, "x"] <- z
    attr(.value, "gradient") <- .grad
    .value
})

If you want to work with expressions it may help to understand that they are organized like lists and that the operators are really Lisp-like functions:

> Z <- y~x+I(x^2)
> Z
y ~ x + I(x^2)
> Z[[1]]
`~`
> Z[[2]]
y
> Z[[3]]
x + I(x^2)
> Z[[3]][[1]]
`+`
> Z[[3]][[2]]
x
> Z[[3]][[3]]
I(x^2)
> Z[[3]][[3]][[1]]
I
> Z[[3]][[3]][[2]]
x^2
> Z[[3]][[3]][[2]][[1]]
`^`

If you want to see a function that will traverse an expression tree, the inimitable Gabor Grothendieck constructed one a few years ago in Rhelp: http://markmail.org/message/25lapzv54jc4wfwd?q=list:org%2Er-project%2Er-help+eval+substitute+expression

于 2013-10-17T23:52:25.087 回答
1

deriv( )的帮助文件中?deriv说函数中的expr参数deriv是“A 表达式或调用或(D 除外)没有 lhs 的公式”。因此,您不能在表达式中使用等式的左侧。

在问题的第二部分,如果我正确理解了你的问题,你可以这样做:说你的 rhs 是 x^2+y^2 并且你需要用 x 和 y 对该表达式进行偏导:

myexp <- expression((x^2) + (y^2))
D.sc.x <- D(myexp, "x")
> D.sc.x
2 * x
D.sc.y <- D(myexp, "y")
> D.sc.y
2 * y

在一行中:

lapply(as.list(c("x","y")),function(a)D(myexp,a))
[[1]]
2 * x

[[2]]
2 * y
于 2013-10-17T22:17:50.907 回答