Here is my R code. The functions are defined as:
f <- function(x, T) {
10 * sin(0.3 * x) * sin(1.3 * x ^ 2) + 0.001 * x ^ 3 + 0.2 * x + 80
}
g <- function(x, T, f=f) {
exp(-f(x) / T)
}
test <- function(g=g, T=1) {
g(1, T)
}
The running error is:
> test()
Error in test() :
promise already under evaluation: recursive default argument reference or earlier problems?
If I substitute the definition of f in that of g, then the error goes away.
I was wondering what the error was? How to correct it if don't substitute the definition of f in that of g? Thanks!
Update:
Thanks! Two questions:
(1) if function test further takes an argument for f, will you add something like test <- function(g.=g, T=1, f..=f){ g.(1,T, f.=f..) } ? In cases with more recursions, is it a good and safe practice adding more .?
(2) if f is a non-function argument, for example g <- function(x, T, f=f){ exp(-f*x/T) } and test <- function(g.=g, T=1, f=f){ g.(1,T, f=f.) }, will using the same name for both formal and actual non-functional arguments a good and safe practice or it may cause some potential trouble?
Formal arguments of the form x=x cause this. Eliminating the two instances where they occur we get the following. (The reason you can't use x=x in the formal arguments of a function definition is that it first looks up the default argument within the function itself so using that form is telling it to use itself as the default but it has not been defined so that makes no sense and we get an error.)
f <- function(x, T) {
10 * sin(0.3 * x) * sin(1.3 * x^2) + 0.001 * x^3 + 0.2 * x + 80
}
g <- function(x, T, f. = f) { ## 1. note f.
exp(-f.(x)/T)
}
test<- function(g. = g, T = 1) { ## 2. note g.
g.(1,T)
}
test()
## [1] 8.560335e-37
If you especify argument evaluation context, you avoid the problem of same name:
f <- function(x) {
10 * sin(0.3 * x) * sin(1.3 * x ^ 2) + 0.001 * x ^ 3 + 0.2 * x + 80
}
g <- function(x, t=1, f=parent.frame()$f) {
exp(-f(x) / t)
}
test <- function(g=parent.frame()$g, t=1) {
g(1,t)
}
test()
[1] 8.560335e-37
As already mentioned, the problem comes from having a function argument defined as itself. However, I want to add an explanation of why this is a problem because understanding that led me to an easier (for me) way to avoid the problem: just specify the argument in the call instead of the definition.
This does not work:
x = 4
my.function <- function(x = x){}
my.function() # recursive error!
but this does work:
x = 4
my.function <- function(x){}
my.function(x = x) # works fine!
Function arguments exist in their own local environment.
R looks for variables first in the local environment, then in the global environment. This is just like how inside a function a variable can have the same name as a variable in the global environment, and R will use the local definition.
Having function argument definitions form their own local environment is why you can have default argument values based on other argument values, like
my.function <- function(x, two.x = 2 * x){}
So this is why you cannot DEFINE a function as my.function <- function(x = x){} but you can CALL the function using my.function(x = x). When you define the function, R gets confused because it finds the argument x = as the local value of x, but when you call the function R finds x = 4 in the local environment you are calling from.
So in addition to fixing the error by changing the argument name or explicitly specifying the environment as mentioned in other answers, you can also just specify that x=x when you call the function instead of when you define it. For me, specifying that x=x in the call was the best solution, since it does not involve extra syntax or accumulating more and more variable names.
I like the G. Grothendieck answer, but I was wondering that is more simple in your case to not include function names in the parameters of functions, like this:
f <- function(x, T) {
10 * sin(0.3 * x) * sin(1.3 * x^2) + 0.001 * x^3 + 0.2 * x + 80
}
g <- function(x, T) {
exp(-f(x)/T)
}
test<- function(T = 1) {
g(1,T)
}
test()
## [1] 8.560335e-37
Related
I would like to have the following generic function, which
checks for thew allowedFormats (This works),
than executes the generic function base on the type of argument x (works)
evaluates the statements after the call of UseMethod() (does not work - as expected)
Now it states in the help for UseMethod
Any statements after the call to UseMethod will not be evaluated as UseMethod does not return.
So this is not surprising. But is there a way that I can achieve this, apart from defining an additional function validate_after() which calls validate() followed by cat(“Validation completed”)?
validate <- function (
x,
allowedFormats
) {
# Check arguments ---------------------------------------------------------
allowedFormats <- c("none", "html", "pdf", "word", "all")
if (!(report %in% allowedFormats)) {
stop("'report' has to be one of the following values: ", allowedFormats)
}
UseMethod("validate", x)
cat(“Validation completed”)
}
Define and call a nested generic
> validate <- function (x, allowedFormats) {
+ .validate <- function(x, allowedFormats) {
+ UseMethod("validate", x)
+ }
+ # Check arguments ---------------------------------------------------------
+ # ...
+ .validate(x, allowedFormats)
+ cat("Validation completed")
+ }
> validate.numeric <- function(x, allowedFormats) {
+ cat('Working...\n')
+ }
> validate(5, NA)
Working...
Validation completed
Depending on what you wish to achieve this might be feasible using the 'on.exit' command, as demonstrated below:
test <- function(x, ...){
if(!is.integer(x))
stop("wups")
on.exit(cat("'On exit' executes after UseMethod, but before the value is returned. x = ", x,"\n"))
UseMethod("test")
}
test.integer <- function(x, ...){
cat("hello i am in a function\n")
x <- x + 3
cat("I am done calculating. x + 3 = ",x,"\n")
return(x)
}
test(1:3)
hello i am in a function
I am done calculating. x + 3 = 4 5 6
'On exit' executes after UseMethod, but before the value is returned. x = 1 2 3
[1] 4 5 6
This is not necessarily a perfect solution. For example if one wished to perform some extra calculations on the methods result, the result is not propagated to the the generic function (as UseMethod does not return). A possible workaround could be to force feed a environment into the called method, to store results in.
I am currently dealing with a problem. I am working on a package for some specific distributions where among other things I would like to create a function that will fit an mixture to some data. For this I would like to use for example the fitdistr function. The problem is that I don't know from what distributions and weights and number of components the mixture will be composed of. Hence I need a function that will dynamically create an density function of some specified mixture so the fitdistr function can use it. For example if the user will call:
fitmix(data,dist=c(norm,chisq),params=list(c(mean=0,sd=3),df=2),wights=c(0.5,0.5))
to use ML method the code needs to create an density function
function(x,mean,sd,df) 0.5*dnorm(x,mean,sd)+0.5*dchisq(x,df)
so it can call optim or fitdistr.
An obvious solution is to use a lot of paste+eval+parse but I don't think this is the most elegant solution. A nice solution is probably hiding somewhere in non-standard evaluation and expression manipulation, but I have not enough skills in this problematic.
P.S. the params can be used as starting values for the optimizer.
Building expressions is relatively straight forward in R with functions like as.call and bquote and the fact that functions are first class objects in R. Building functions with dynamic signatures is a bit trickier. Here's a pass at some function that might help
to_params <- function(l) {
z <- as.list(l)
setNames(lapply(names(z), function(x) bquote(args[[.(x)]])), names(z))
}
add_exprs <- function(...) {
x <- list(...)
Reduce(function(a,b) bquote(.(a) + .(b)), x)
}
get_densities <- function(f) {
lapply(paste0("d", f), as.name)
}
weight_expr <- function(w, e) {
bquote(.(w) * .(e))
}
add_params <- function(x, p) {
as.call(c(as.list(x), p))
}
call_with_x <- function(fn) {
as.call(list(fn, quote(x)))
}
fitmix <- function(data, dist, params, weights) {
fb <- Reduce( add_exprs, Map(function(d, p, w) {
weight_expr(w, add_params(call_with_x(d), to_params(p)))
}, get_densities(dist), params, weights))
f <- function(x, args) {}
body(f) <- fb
f
}
Note that I changed the types of some of your parameters. The distributions should be strings. The parameters should be a list of named vectors. It would work with a call like this
ff <- fitmix(data, dist=c("norm","chisq"), params=list(c(mean=0,sd=3),c(df=2)),
weights=c(0.5,0.5))
It returns a function that takes an x and a list of named arguments. You could call it like
ff(0, list(mean=3, sd=2, df=2))
# [1] 0.2823794
which returns the same value as
x <- 0
0.5 * dnorm(x, mean = 3, sd = 2) + 0.5 * dchisq(x, df = 2)
# [1] 0.2823794
Suppose you define a function in R using the following code:
a <- 1
f <- function(x) x + a
If you latter redefine a you will change the function f. (So, f(1) = 2 as given but if you latter on redefine a =2 then f(1) = 3. Is there a way to force R to use the value of a at the time it compiles the function? (That is, f would not change with latter redefinitions of a).
The above is the shortest case I could thought of that embodies the problem I am having. More specifically, as requested, my situation is:
I am working with a bunch of objects I am calling "person". Each person is defined as a probability distribution that depends on a n dimensional vector $a$ and a n dimensional vector of constrains w (the share of wealth).
I want to create a "society" with N people, that is a list of N persons. To that end, I created two n by N matrices A and W. I now loop over 1 to N to create the individuals.
Society <- list()
### doesn't evaluate theta at the time, but does w...
for (i in 1:Npeople) {
w <- WealthDist[i,]
u <- function(x) prod(x^A[i,])
P <- list(u,w)
names(P) <- c("objective","w")
Society[[length(Society)+1]] <- P
}
w gets is pass-by-value, so each person gets the right amount of wealth. But A is pass-by-reference -- everybody is being assigned the same function u (namely, the function using i = N)
To finish it up, the next steps are to get the Society and, via two optimizations get an "equilibrium point".
You can create a function which uses a locked binding and creates a function to complete your purpose. The former value of a will be used for w which will be stored in the environment of the function and will not be replaced by further values changes of a.
a <- 1
j <- new.env() # create a new environment
create.func <- function () {
j$w <<- a
function (x) {
x+ j$w
}
}
f <- create.func()
a <- 2
f(2)
[1] 3 # if w was changed this should be 4
Credits to Andrew Taylor (see comments)
EDIT: BE CAREFUL: f will change if you call create.func, even if you do not store it into f. To avoid this, you could write this code (it clearly depends on what you want).
a <- 1
create.func <- function (x) {
j <- new.env()
j$w <- a
function (x) {
x + j$w
}
}
f <- create.func()
f(1)
[1] 2
a <- 2
q <- create.func()
q(1)
[1] 3
f(1)
[1] 2
EDIT 2: Lazy evaluation doesn't apply here because a is evaluated by being set to j$w. If you had used it as an argument say:
function(a)
function(x)
#use a here
you would have to use force before defining the second function, because then it wouldn't be evaluated.
EDIT 3: I removed the foo <- etc. The function will return as soon as it is declared, since you want it to be similar to the code factories defined in your link.
EDIT by OPJust to add to the accepted answer that in spirit of
Function Factory in R
the code below works:
funs.gen <- function(n) {
force(n)
function(x) {
x + n
}
}
funs = list()
for (i in seq(length(names))) {
n = names[i]
funs[[n]] = funs.gen(i)
}
R doesn't do pass by reference; everything is passed to functions by value. As you've noticed, since a is defined in the global environment, functions which reference a are referencing the global value of a, which is subject to change. To ensure that a specific value of a is used, you can use it as a parameter in the function.
f <- function(x, a = 1) {
x + a
}
This defines a as a parameter that defaults to 1. The value of a used by the function will then always be the value passed to the function, regardless of whether a is defined in the global environment.
If you're going to use lapply(), you simply pass a as a parameter to lapply().
lapply(X, f, a = <value>)
Define a within f
f <- function(x) {a<-1;x + a}
Why does
f <- function(a) {
g <- function(a=a) {
return(a + 2)
}
return(g())
}
f(3) # Error in a + 2: 'a' is missing
cause an error? It has something to do with the a=a argument, particularly with the fact that the variable names are the same. What exactly is going on?
Here are some similar pieces of code that work as expected:
f <- function(a) {
g <- function(a) {
return(a + 2)
}
return(g(a))
}
f(3) # 5
f <- function(a) {
g <- function(g_a=a) {
return(g_a + 2)
}
return(g())
}
f(3) # 5
g <- function(a) a + 2
f <- function(a) g(a)
f(3) # 5
The problem is that, as explained in the R language definition:
The default arguments to a function are evaluated in the evaluation frame of the function.
In your first code block, when you call g() without any arguments, it falls back on its default value of a, which is a. Evaluating that in the "frame of the function" (i.e. the environment created by the call to g()), it finds an argument whose name matches the symbol a, and its value is a. When it looks for the value of that a, it finds an argument whose name matches that symbol, and whose value is a. When...
As you can see, you're stuck in a loop, which is what the error message is trying to tell you:
Error in g() :
promise already under evaluation: recursive default argument reference or
earlier problems?
Your second attempt, which calls g(a) works as you expected, because you've supplied an argument, and, as explained in the same section of R-lang:
The supplied arguments to a function are evaluated in the evaluation frame of the calling function.
There it finds a symbol a, which is bound to whatever value you passed in to the outer function's formal argument a, and all is well.
The problem is the a=a part. An argument can't be its own default. That is a circular reference.
This example may help clarify how it works:
x <- 1
f <- function(a = x) { x <- 2; a }
f()
## [1] 2
Note that a does not have the default 1; it has the default 2. It looks first in the function itself for the default. In a similar way a=a would cause a to be its own default which is circular.
I am trying to combine multiple expressions in R into a single expression. Ideally, I would be able to do something like this:
g <- expression(exp(a[1]*x)/(1 + exp(a[1]*x)))
h <- expression(exp(a[2]*x)/(1 + exp(a[2]*x)))
c <- expression(g * h)
where a is a given vector of data and x is the only unknown (and it is the same unknown across all expressions). c would return
R> c
expression(exp(a[1]*x)/(1 + exp(a[1]*x)) * exp(a[2]*x)/(1 + exp(a[2]*x)))
Right now, when I do this I just get
R> c
expression(g * h)
I want to have an equation
(source: lehrfeld.me)
into which I could plug some vector a to obtain a function of x. What am I doing wrong here?
Don't use expressions, use functions. The
From what I can decipher, the following will do what you want
# a function for a vector `x` and single value `a`
func <- function(x,a) { (exp(1)^(a*x)/(1 + exp(1)^(a*x))) }
# a function for a vector `x` and vector length 2 for `a`
foo <- function(x, a){func(x,a[1]) * func(x, a[2])}
# call the function to calculate what you want.
foo(x,a)
And if you want the expression associated with this so you can plot the text of the equation, the following will work
expr <- expression(exp(1)^(a*x)/(1 + exp(1)^(a*x))
g <- do.call(substitute, list(as.list(expr)[[1]], env= list(a=3)))
h<- do.call(substitute, list(as.list(expr)[[1]], env= list(a=2)))
'%c%' <- function(a,b) bquote(.(a) %*% .(b))
fooExpr <- g %c% h
this is an old question but surprisingly, no easy answer has been given. As said in a comment, "R is not a symbolic algebra program"; however, R has all necessary means for manipulating expressions. I have no idea how to do it with expressions (in the technical sense, see ?expression) but it is trivially easy with calls:
g <- quote(exp(a[1]*x)/(1 + exp(a[1]*x)))
h <- quote(exp(a[2]*x)/(1 + exp(a[2]*x)))
substitute(g*h, list(g=g, h=h))
# exp(a[1] * x)/(1 + exp(a[1] * x)) * (exp(a[2] * x)/(1 + exp(a[2] * x)))
There are probably easier ways to achieve what you want (maybe using functions) but this is the easiest way to merge two "calls" (i.e. expressions in the "colloquial" sense as defined by R wizards).
Creating the expression from other expressions is more straightforward (IMO) using rlang, than base R. Use the !! (bang-bang) to force evaluation of an object within an expression.
library(rlang)
a <- c(2, 3)
g <- expr(exp(!!a[1] * x) / (1 + exp(!!a[1] * x)))
h <- expr(exp(!!a[2] * x) / (1 + exp(!!a[2] * x)))
c <- expr(!!g * !!h)
c
#> exp(2 * x)/(1 + exp(2 * x)) * (exp(3 * x)/(1 + exp(3 * x)))
Created on 2020-03-21 by the reprex package (v0.3.0)
You may want a function not an expression I think:
newfunc <- function(x) {
(exp(1)^(2*x)/(1 + exp(1)^(2*x))) *
(exp(1)^(3*x)/(1 + exp(1)^(3*x)))
}
a <- 1:10
newfunc(a)
[1] 0.8390245 0.9795856 0.9974043 0.9996585 0.9999543 0.9999938 0.9999992
[8] 0.9999999 1.0000000 1.0000000
If you want to chain together multiple functions explicitly, you could just do:
newfunc1 <- function(x) {
(exp(1)^(2*x)/(1 + exp(1)^(2*x)))
}
newfunc2 <- function(x) {
(exp(1)^(3*x)/(1 + exp(1)^(3*x)))
}
newfunc1(a) * newfunc2(a)
Keep in mind, as the help file at ?expression says:
‘Expression’ here is not being used in its colloquial sense, that
of mathematical expressions. Those are calls (see ‘call’) in R,
and an R expression vector is a list of calls, symbols etc, for
example as returned by ‘parse’.
You could define a binary function to combine expression objects in a slightly hacky way -- get their character representation, paste them with a *, then re-parse it:
"%c%" <- function(x, y) parse( text=paste(x, "*", y) )
gives the desired output when calling g %c% h, for example.
EDIT: Answer updated to correct previous error; thanks mnel!