What is R's equivalent to Matlab's subs(f, x, value) for symbolic substitution?

Viewed 225

In Octave, I use the following to differentiate a function of 2-variables and then substitute 0 for x using subs(). Basically in doing moment-generating-function, Taylor series expansion, etc, we differentiate and then substitute some a for x. I am not able to find the equivalent substitution function in R. Can you please let me know how to do it? Thanks

pkg load symbolic; #octave symbolic package
syms lamb, x; #declare lamb, x symbols
mgf = lamb / (lamb - x); #moment generating function of exponential
mgf1 = diff(mgf, x, 1); #1st differivative
mgf1_0 = subs(mgf1, x, 0); #substitute 0 for E(X)
3 Answers

Using base R:

f <- quote( lambda / (lambda - x) )
Df <-  D(f, "x")

do.call("substitute", list(Df, list(x = 0)))
## lambda/(lambda - 0)^2

or we can evaluate Df at specific x and lambda values:

eval(Df, list(x = 0, lambda = 3))
## [1] 0.3333333

Create function to represent result

We can use Df to define an R function der which evaluates the derivative at specific x and lambda values.

der <- function(x, lambda) {}
body(der) <- Df
der(0, 3)
## [1] 0.3333333

Currying

If we want to set x to 0 and create the resulting function of lambda

make_der0 <- function(x = 0) function(lambda) der(x, lambda)
der0 <- make_der0()
der0(3)
## [1] 0.3333333

This is known as currying or partialling and various packages have this as well:

library(functional)
der0a <- Curry(der, x = 0)
der0a(3)
## [1] 0.3333333

library(purrr)
der0b <- partial(der, x = 0)
der0b(3)
## [1] 0.3333333

This appears to be using the symbolic package, which in turn depends on the sympy Python library. R doesn't have built-in symbolic manipulation capabilities, but it does (TIL) have an rSymPy package that works similarly.

## https://kevinkotze.github.io/mm-tut1-symbolic/
library(rSymPy)

rSymPy doesn't have a built-in subs() function, so we'll define one:

subs <- function(expr,x,y) {
    Sym(expr,".subs(",x,",",y,")")
}

Also useful to define this (not sure if there's a better way):

r_eval <- function(s,eval_list) {
   eval(parse(text=sympy(unclass(s))), eval_list)
}

The rest of the code looks almost identical to the Octave code. Define variables:

## NOTE: 'lambda' is a reserved word in Python, so trying to use it as 
## a variable gives rise to confusing errors ...
lam <- Var("lam")
x <- Var("x")
f <- lam/(lam-x)

Differentiate:

mgf1 <- deriv(f,x,1)

Substitute:

subs(mgf1,x,0)

There are other interfaces from R to symbolic math engines, e.g. Ryacas.

If you want to compute the second moment by calculating f''(0), that's not much harder:

v <- subs(deriv(f,x,2),x,0)  ## "2/lam**2"
r_eval(v, list(lam=5))  ## 0.08

Maybe you can try package Deriv

library(Deriv)
f <- function(l,x) l/(l-x)
fprim <- Deriv(f,"x")(2,0) 

such that

> fprim(2,0)
[1] 0.5
Related