R is a function-oriented language. Basically every object manipulation is done with functions. It is possible that during a data analysis we are only using functions from the different packages, but it is useful to write our own functions as well. The main purpose is to avoid code repetition. As a rule of a thumb, if you need to do the same thing more than twice -> write a function instead.
f <- function(){
cat("Hello world! \n")
}
f()
## Hello world!
f <- function(num1, num2){
res <- num1+num2
res
}
f(1,2)
## [1] 3
## [1] 1
## [1] 2
f(num2=2, num1=1)
## [1] 1
## [1] 2
f(2, num1=1)
## [1] 1
## [1] 2
try(f(2))
## [1] 2
## Error in print(num2) : argument "num2" is missing, with no default
## [1] 1
## [1] 2
f(num2=2, num1=1)
## [1] 1
## [1] 2
f(2)
## [1] 2
## [1] 3
The functions are working in their own environment. This environment can’t be seen from the outside. E.g. if you define a variable within the function, it won’t be available outside the function. There are certain rules of what variables can be seen from inside the function’s environment. Lexical scoping - searches the environment where the function was defined.
g <- function(x) {
x*y
}
try(g(2))
## Error in g(2) : object 'y' not found
y <- 10
g(2)
## [1] 20
## Error in mean.default() : argument "x" is missing, with no default
## Error in print(ab) : object 'ab' not found
Why?
ls(environment(g))
## [1] "f" "g" "x" "y"
#ls(environment(mean))
search()
## [1] ".GlobalEnv" "package:stats" "package:graphics"
## [4] "package:grDevices" "package:utils" "package:datasets"
## [7] "package:methods" "Autoloads" "tools:callr"
## [10] "package:base"
Due to the own environment, it can be difficult what goes wrong within the function. Useful functions:
traceback()
browser()
debug()
options(error=recover)
options(error=stop)