Function of x as input in function argument - r

I have written a function to approximate a derivate in a point x in R like this:
nderiv<- function(f,x,h){
(f(x+h)-f(x))/h
}
And want to make an input in f as either x^2, "x^2" or as a predefined function like:
ex<- function(x){
x^2
}
The code works fine if you use the last example (using a predefined function). But I can't get it to work when inserting the other options.
I either get the error
Error in nderiv(x^2, 1) : object 'x' not found
or
Error in nderiv("x^2", 1, 1e-04) : could not find function "f"
So I would like to be able to write nderiv(x^2,1,0.0001) or nderiv("x^2",1,0.0001) and get the value 2.0001.
Thanks in advance!

If you want to use x^2 as an anonymous function, pass it to nderiv as function(x){x^2}. Something like:
nderiv(function(x){x^2}, 1, 0.0001)

Related

How to use object from another function in a function without explicitely passing it to the function

I'm sure there's already an answer to it, but I'm not sure about the right terms to search for.
I thought that in R, functions that need an argument that is not defined in the function will look for said argument in the environment they are called from / the parent environment, no?
So I thought, the following would work:
f_xyz <- function (y, z)
{
x + y + z
}
f_x <- function()
{
x <- 1
y <- 2
z <- 3
f_xyz(y, z)
}
f_x()
x is defined and created in the f_x function, so when calling the f_xyz function WITHIN f_x, I thought it will find x there and use it. However, that is not the case. Instead I'm getting an error Error in f_xyz(y, z) : object 'x' not found.
If I create the f_xyz function in f_x, the error doesn't appear.
What am I missing?
f_x <- function()
{
f_xyz <- function (y, z)
{x + y + z}
x <- 1
y <- 2
z <- 3
f_xyz(y, z)
}
f_x()
[1] 6
R uses lexical scoping:
the values of free variables are searched for in the environment in which the function was defined.
Function f_xyz was defined in the global env, but x was defined in the env of f_x, resulting in the error 'object not found'. In the latter case, both f_xyz and x were defined in the same scope, so they can share their arguments.
Other languages like Python use enclosing scopes for nested functions, but R doesn't.
See here for details.
Nevertheless, you probably want to use partial evaluation to set some arguments and mention x explicitly in the function. It is very messy to write a function relying on something else than its arguments.

Find Anti-derivative in R

I want to be able to find the anti-derivative of an arbitrary function in R.
Suppose I´ve got f = 1/(2*x^2) and want to find F, which by the way is easy to calculate by hand.
I´ve tried the following:
f<- function (x) {1/(sqrt(x))}
F = antiD(f)
This gives me:
Error: no applicable method for 'rhs' applied to an object of class "function"
Can someone give me a push in the right direction here?
Are you using the mosaicCalc package?
I don't think you can use a function as argument to the antiD(). It expects a formula:
F <- antiD( 1/sqrt(x) ~ x)
This will give you a function F that takes two parameters x and C (constant). In this instance, it can't do a symbolic integration as it doesn't know what to do with the sqrt() function. If you alternatively did:
F <- antiD(x^-0.5 ~ x)
Then you'll see that symbolic integration has been done:
F
function (x, C = 0) {2 * x^(1/2) + C}
With Ryacas:
library(Ryacas)
yac_str("Integrate(x) 1/Sqrt(x)")
# [1] "2*Sqrt(x)"

How to turn a simple text expression into a mathematical expression in R

Right now I am trying to solve a question concerning establishing a function to calculate the log of the moment generating functions in R. The required procedure is the user could input any random density function f(x) with the interval of the random variable. However, I have no idea how to let R identify the input string of the function expression, say "x^2-4*x", and turn it into a workable mathematical expression or say function. Can anybody help?
mgf <- function(expr, t, from=NULL, to=NULL){
moment <- NULL
for (i in 1:length(t)){
moment <- c(moment,integrate(exp(x*t[i])*(expr),lower=from,upper=to))
}
return(moment)
}
This is the code I'm currently having. Obviously, it won't work. What I want is users can input an expression, like x^2-4*x, which is the value of expr, and then turn the expr into part of the function the integrate() function can evaluate.
You can try:
library(functional)
mgf = function(stringFormula, t, from=NULL, to=NULL)
{
f = function(x, i) exp(x*i)*eval(parse(text=stringFormula))
sapply(t, function(u) integrate(Curry(f, i=u), lower=from, upper=to)[[1]])
}
The point is, you need to pass character string x as variable in your stringFormula argument:
mgf("x^2-4*x", 1:5, from=0, to=1)
#[1] -3.281718 -6.791792 -14.652785 -32.698902 -74.976232

How do I draw a curve of a function created by another function?

I want to draw the curve of function f generated by fmaker, the following way errs:
fmaker <- function(a) function(x) a*x
curve(fmaker(2), 0, 10)
Error in curve(fmaker(2), 0, 10) :
'expr' must be a function, or a call or an expression containing 'x'
but if I assign fmaker(2) to an variable g, it works:
g <- fmaker(2)
curve(g, 0, 10)
It appear strange to me because when using other functions like lapply, these won't make any difference:
lapply(list(1,2), g)
lapply(list(1,2), fmaker(2))
#both output correct answer
Could anybody tell me why? What's so special about curve?
The reason is that curve is using non-standard evaluation on its first argument – rather than evaluating the expression, then passing it to curve as an argument, R passes the unevaluated expression to curve.
curve then attempts to evaluate the expression in its own context when it sees that the expression is a function call:
sexpr <- substitute(expr)
…
if (!((is.call(sexpr) || is.expression(sexpr)) && xname %in%
all.vars(sexpr)))
stop(gettextf("'expr' must be a function, or a call or an expression containing '%s'",
xname), domain = NA)
expr <- sexpr
Where xname = 'x', and all.var is a function which returns all variables contained in an unevaluated expression.
This obviously fails (since curve(2) contains no x). Your second example succeeds because now you’re not passing a function call expression to curve, you’re passing it a single variable (referring to a function), so curve evaluates it by just calling it normally:
if (is.name(sexpr)) {
expr <- call(as.character(sexpr), as.name(xname))
}
(Edit) Note: this does not answer the OP question (function that returns function), but a more typical case.
You need to include 'x' in the function call:
fmaker <- function(x, a) a*x
curve(fmaker(x, a=2), 0, 10)

R: how to pass functions as arguments to another function

Suppose I want to integrate some function that involves sums and products of a few other user defined functions. Lets take an extremely simple example, it gives the same error.
integrate(f = sin + cos, lower=0, upper=1)
This yields "Error in sin + cos : non-numeric argument to binary operator" which I think is saying it doesn't make sense to just add functions together without passing them some sort of argument. So I am a bit stuck here. This thread poses what I think is a solution to a more complicated question, that can be applied here, but it seems long for such a simple task in this case. I'm actually kind of surprised that I am unable to find passing function arguments to functions in the help manual so I think I am not using the right terminology.
Just write your own function:
> integrate(f = function(x) sin(x) + cos(x), lower=0, upper=1)
1.301169 with absolute error < 1.4e-14
In this example I've used an anonymous function, but that's not necessary. The key is to write a function that represents whatever function you want to integrate over. In this case, the function should take a vector input and add the sin and cos of each element.
Equivalently, we could have done:
foo <- function(x){
sin(x) + cos(x)
}
integrate(f = foo, lower=0, upper=1)
This is an old question, but I recently struggled with it, so here is a simple example in case it helps others in the future. #joran's answer is still the best.
Define your first function: f1 <- function(x){return(x*2)}
Test it: f1(8) (expect 8*2=16); returns [1] 16
Define your second function: f2 <-function(f, y){return(f+y)}
Test it: f2(f=f1(8), y=1) (expect 8*2 = 16 +1 = 17); returns [1] 17

Resources