R enables many ways to manipulate functions. A function in R has a body and formal arguments. Moreover, a function has an environment where it was created and an environment where it was called. match.fun can be used to find a function by its name.
f0 <- function(x = 5) x * 100
body(f0) ## the body of the function
formals(f0) ## the formal arguments
match.fun("f0")(10) ## find a function by name
it is possible to create a function call and to evaluate this function call in a different environment. The function eval has the envir argument to define an environment where this expression should be evaluated.
f1 <- function(x) x + 5
calltof1 <- call("f1", 10)
eval(calltof1)
With do.call one can supply the arguments of a function as a list. One idea would be to conduct functions with different arguments by updating the list of arguments.
What is the effect of invisible? In which situations could we use suppressWarnings?
f3 <- function(x,y){
values <- rnorm(x, mean = y)
out <- plot(hist(values))
return(invisible(values))
}
f3(50, 5)
The definition of functions inside of other functions enables nameless or anonymous functions. In the next example the second function has no name.
f4 <- function(x, ...){
y = 5 * x
function(z, ...){
return(z + y)
}
}
f4(2)
f4(2)(5)
Handeling conditions (errors) is a main issue. The function try tests whether an expression (function call) can be conducted successfully. If there is no error the value will be returned. If an error occurred the output object will be of the class "try-error".
f5 <- function(x){
condition <- try(log(x))
if(class(condition) == "try-error" ){
stop("Error with the log function")
} else {
return(condition)
}
}
f5("A") ## This will give two errors. Which makes more sense?
f5(10)
Task: Write a function named recursive. This functions takes as input a function f and a value x. f should be applied two times to x. In other words: recursive (log, 100) == log(log(100))
In object oriented programming a developer defines objects (S3 or S4) that will have class names (like ExpressionSet). Generic functions apply different methods in dependance of the input object and will return objects of a desired class. An example: If you want to plot a matrix or a vector you call (the generic) plot function. This function calls now the right method for a matrix or a vector.
R enables many ways to manipulate functions. A function in R has a body and formal arguments. Moreover, a function has an environment where it was created and an environment where it was called.
match.fun
can be used to find a function by its name.it is possible to create a function call and to evaluate this function call in a different environment. The function
eval
has theenvir
argument to define an environment where this expression should be evaluated.With
do.call
one can supply the arguments of a function as a list. One idea would be to conduct functions with different arguments by updating the list of arguments.What is the effect of
invisible
? In which situations could we usesuppressWarnings
?The definition of functions inside of other functions enables nameless or anonymous functions. In the next example the second function has no name.
Handeling conditions (errors) is a main issue. The function
try
tests whether an expression (function call) can be conducted successfully. If there is no error the value will be returned. If an error occurred the output object will be of the class"try-error"
.Task: Write a function named
recursive
. This functions takes as input a functionf
and a valuex
.f
should be applied two times tox
. In other words:recursive (log, 100) == log(log(100))
In object oriented programming a developer defines objects (S3 or S4) that will have class names (like
ExpressionSet
). Generic functions apply different methods in dependance of the input object and will return objects of a desired class. An example: If you want to plot a matrix or a vector you call (the generic)plot
function. This function calls now the right method for a matrix or a vector.Here is a definition of a generic function named
label_it
:This function can now process two classes of input objects.