Is there a function in R, which treats evaluates variable and call it if it's class is function.
a <- 1
b <- function() 2
So I expect return from evaluation of a and do.call(b) automatically understanding that second one is a function and evaluating it.
Of course i can make a check with is.function() and call do.call and in other cases call eval, but I thought it might be already done.
> eval(a)
[1] 1
> do.call(a, args = list())
Error in do.call(a, args = list()) :
'what' must be a character string or a function
> eval(b)
function() 2
> do.call(b, args = list())
[1] 2
I do expect
a <- 1
b <- function() 2
> someFun(a)
1
> someFun(b)
2
It’s hard to prove a negative but I rather doubt that there’s a function which will evaluate non-function variables to their value, and function-variables to the result of making them into a call and executing the call — because these two are fundamentally different operations.
That said, as you realised it’s easy enough to do yourself. Even easier in fact: no do.call needed:
evaluate = function (obj)
if(is.function(obj)) obj() else obj
Related
I still a novice in R, and still understanding lazy evaluation. I read quite a few threads on SO (R functions that pass on unevaluated arguments to other functions), but I am still not sure.
Question 1:
Here's my code:
f <- function(x = ls()) {
a<-1
#x ##without x
}
f(x=ls())
When I execute this code i.e. f(), nothing returns. Specifically, I don't see the value of a. Why is it so?
Question 2:
Moreover, I do see the value of a in this code:
f <- function(x = ls()) {
a<-1
x ##with x
}
f(x=ls())
When I execute the function by f() I get :
[1] "a" "x"
Why is it so? Can someone please help me?
Question 1
This has nothing to do with lazy evaluation.
A function returns the result of the last statement it executed. In this case the last statement was a <- 1. The result of a <- 1 is one. You could for example do b <- a <- 1 which would result in b being equal to 1. So, in this case you function returns 1.
> f <- function(x = ls()) {
+ a<-1
+ }
> b <- f(x=ls())
> print(b)
[1] 1
The argument x is nowhere used, and so doesn't play any role.
Functions can return values visibly (the default) or invisibly. In order to return invisibly the function invisible can be used. An example:
> f1 <- function() {
+ 1
+ }
> f1()
[1] 1
>
> f2 <- function() {
+ invisible(1)
+ }
> f2()
>
In this case f2 doesn't seem to return anything. However, it still returns the value 1. What the invisible does, is not print anything when the function is called and the result is not assigned to anything. The relevance to your example, is that a <- 1 also returns invisibly. That is the reason that your function doesn't seem to return anything. But when assigned to b above, b still gets the value 1.
Question 2
First, I'll explain why you see the results you see. The a you see in your result, was caused some previous code. If we first clean the workspace, we only see f. This makes sense as we create a variable f (a function is also a variable in R) and then do a ls().
> rm(list = ls())
>
> f <- function(x = ls()) {
+ a<-1
+ x
+ }
> f(x=ls())
[1] "f"
What the function does (at least what you would expect), if first list all variables ls() then pass the result to the function as x. This function then returns x, which is the list of all variables, which then gets printed.
How this can be modified to show lazy evaluation at work
> rm(list = ls())
>
> f <- function(x) {
+ a <<- 1
+ x
+ }
>
> f(x = ls())
[1] "a" "f"
>
In this case the global assignment is used (a <<- 1), which creates a new variable a in the global workspace (not something you normally want to do).
In this case, one would still expect the result of the function call to be just f. The fact that it also shows a is caused by lazy evaluation.
Without lazy evaluation, it would first evaluate ls() (at that time only f exists in the workspace), copy that into the function with the name x. The function then returns x. In this case the ls() is evaluated before a is created.
However, with lazy evaluation, the expression ls() is only evaluated when the result of the expression is needed. In this case that is when the function returns and the result is printed. At that time the global environment has changed (a is created), which means that ls() also shows a.
(This is also one of the reasons why you don't want functions to change the global workspace using <<-.)
Naively, I thought that R's ... notation would collect all named arguments that appear after it so that they can be passed along. For example:
> a <- function(..., arg=TRUE) b(...)
> b <- function(arg=TRUE) print(arg)
> a(arg=FALSE)
[1] TRUE # I would want this to be FALSE
Since this clearly doesn't happen, is there some way to package up all of the arguments supplied to a function so that they get sent along?
You will need to pass arg:
a <- function(..., arg=TRUE) b(..., arg = arg)
I'm writing some R code and I want to store a list of Function names and what they are for in a dataframe, and then query that dataframe to determine which function to call, but I can't figure out how to do this, or if it's even possible.
As a basic example, let's assume the function name is just stored as a string in a variable, how do I call the function based on the function name stored in that variable?
MyFunc <-function() {
# Do some stuff...
print("My Function has been called!!!")
return(object)
}
FuncName <- "MyFunc()"
Result <- FuncName
I need to make
Result <- FuncName
Work the same as
Result <- MyFunc()
Also, passing objects, or other variables, to the functions is not a concern for what I am doing here, so those () will always be empty. I realize passing variables like this might get even more complicated.
You could use get() with an additional pair of ().
a<-function(){1+1}
var<-"a"
> get(var)()
[1] 2
To get a function from its name, try match.fun, used just like get in the answer provided by #Alex:
> a <- function(x) x+1
> f <- "a"
> match.fun(f)(1:3)
[1] 2 3 4
To call a function directly using its name, try do.call:
> params <- list(x=1:3)
> do.call(f, params)
[1] 2 3 4
The advantage to do.call is that the parameters passed to the function can change during execution (e.g., values of the parameter list can be dynamic at run time or passed by the user to a custom function), rather than being hardwired in the code.
Why do I suggest match.fun or do.call over get? Both match.fun and do.call will make sure that the character vector ("a" in the above examples) matches a function rather than another type of object (e.g., a numeric, a data.frame, ...).
Consider the following:
# works fine
> get("c")(1,2,3)
[1] 1 2 3
# create another object called "c"
> c <- 33
> get("c")
[1] 33
#uh oh!!
> get("c")(1,2,3)
Error: attempt to apply non-function
# match.fun will return a function; it ignores
# any object named "c" that is not a function.
> match.fun("c")(1,2,3)
[1] 1 2 3
# same with do.call
> do.call("c", list(1,2,3))
[1] 1 2 3
While constructing a function I discovered, that complex numbers are disjoint when setting the function body:
funCplx <- function () {}
formals(funCplx) <- alist(t=)
body(funCplx) <- as.call(c(as.name("{"), parse(text = "t*(2+3i)")))
funCplx
funCplx(3)
As you can see, the function returns the correct value, but contains t * (2+(0+3i)). It is disjoint within the c(). The expression c(parse(text = "t*(2+3i)")) returns the disjoint term, whereas parse(text = "t*(2+3i)") returns t*(2+3i).
Why is the expression disjoint in the body?
Edit: I add an argument to the function. I removed it for sparseness, but it gets necessary to get the correct solution.
Edit 2: Most answers assume I know the complex number (here 2+3i). I took this example, because it is minimal.
In my real case, I take many complex numbers from variable matrices and put them together in one function with additional variables (here t) and functions like exp. In my first step I paste different parts and parse this text into the function body.
To point out my question: Is it bad that the complex number is disjoint in the parse function in case of calculation steps? Reworded: Does R need more calculation steps to calculate 5*(2+(0+3i)) than 5*(2+3i)?
Why not:
funCplx <- function () {}
formals(funCplx) <- alist()
body( funCplx) <- as.call(c(as.name("{"), eval(parse(text = "2+3i"))) )
funCplx
funCplx()
Returns:
funCplx
#----console displays---
function ()
{
2+3i
}
With the added request to include extra arguments in what appears when the function is print-ed, you could make it look more "finished" by assigning the fixed value to a name and then using that name in the expression:
funCplx <- function () {}
formals(funCplx) <- alist(t=)
environment(funCplx) <- new.env()
environment(funCplx)$cplx <- (2+3i)
body(funCplx) <- quote(t*cplx)
funCplx
# function (t)
# t * cplx
funCplx(3)
# [1] 6+9i
And testing to see if the earlier flimsy construction error was fixed:
> cplx=42
> funCplx(7)
[1] 14+21i
The earlier method didn't create an environment for funCplx and so its environment was .GlobalEnv. This version will carry 'cplx' around with it.
To create an expression that multiplies an argument by a given complex constant, use this:
funCplx <- function () {}
formals(funCplx) <- alist(t=)
body(funCplx) <- as.call(c(as.name("{"), call("*", as.symbol("t"), 2+3i)))
funCplx
funCplx(3)
Note that this avoids evaluation of 2 + (0+3i) at "run-time", since the constant is "hard-coded" in the function's body:
> body(funCplx)[[2]][[3]]
[1] 2+3i
> is(body(funCplx)[[2]][[3]])
[1] "complex" "vector"
I'm trying to write a function that captures the arguments of the function it is called from. For example,
get_args <- function () as.list( sys.call(sys.parent()) )[-1]
caller <- function (x, y, z) {
get_args()
}
caller(1,2,3)
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
sys.call() unfortunately does not add match parameter names with argument values, and I'd like to write a similar version of get_args that returns output similar to
caller2 <- function (x, y, z) {
as.list( match.call() )[-1]
}
caller2(1,2,3)
$x
[1] 1
$y
[1] 2
$z
[1] 3
replacing "get_args()" with "match.call()" directly is not the solution I'm looking for, since in reality get_args will do some other things before returning its parent functions arguments.
I've tried to use match.call() with sys.parent() in several ways, but I can't get the function to return the arguments of caller; it just returns the arguments of get_args().
Is there any way to make get_args() return output identical to that of caller2 for the above test case? I know that naming the arguments manually is possible using formals(), but is this guaranteed to be equivelant?
If any clarification is needed, leave a comment below. Thanks.
EDIT 1:
the aim of get_args() is to act as a user-friendly way of getting the arguments with which a function was called. Typing as.list( match.call() )[-1] gets old, but because match.call grabs the nearest function call it just gets the arguments of get_args() at the moment.
get_args() will also get default arguments from the parent function, but this easy to implement.
SOLUTION:
thanks Hong Ooi, the key to using match.call seems to be providing both the call and the definition of the function you want to find out about. A slightly modified, anonymous-friendly version of get_args is below for posterity
get_args <- function () {
as.list( match.call(
def = sys.function( -1 ),
call = sys.call(-1)) )[-1]
}
This version finds the function further up the call stack, grabs its definition and call, and matches parameters to its arguments.
get_args <- function()
{
cl <- sys.call(-1)
f <- get(as.character(cl[[1]]), mode="function", sys.frame(-2))
cl <- match.call(definition=f, call=cl)
as.list(cl)[-1]
}
The key here is to set the definition argument to match.call to be get_arg's calling function. This should (hopefully!) work for the general case where get_args can be called from anywhere.