Semillero de R
2016
1) What are the three components of a function?
2) What does the following code return?
y <- 10
f1 <- function(x) {
function() {
x +10
}
}
f1(1)()
3) How would you more typically write this code?
+(1,*(2,3))
4) Does the following function throw an error when called? Why/why not?
f2 <- function(a, b) {
a * 10
}
f2(10, stop("This is an error!"))
5) What is an infix function?
When you need to create a function you should take clear:
myfunction <- function(arg1, arg2, arg3, ...) {
line 1
line 2
line 3
.
.
.
}
Create a function, called f1, which adds a pair of numbers.
f1 <- function(x, y) {
x + y
}
Or
f1 <- function(x, y) {
return(x + y)
}
If we have a function which performs multiple tasks and therefore has multiple results to report then we have to include a return statement with c() or list() inside the function is order to see all the results.
f2 <- function(x, y) {
z1 <- 2*x + y
z2 <- x + 2*y
z3 <- 2*x + 2*y
z4 <- x/y
return(c(z1, z2, z3, z4))
}
f2 <- function(x, y) {
z1 <- 2*x + y
z2 <- x + 2*y
z3 <- 2*x + 2*y
z4 <- x/y
return(list(z1, z2, z3, z4))
}
All R functions have three parts:
f <- function(x) x^2
f(3)
[1] 9
formals(f)
$x
body(f)
x^2
environment(f)
<environment: R_GlobalEnv>
formals(f) <- alist(x=5)
f()
[1] 25
body(f) <- expression(x^3+100)
f(3)
[1] 127
Predict the output of the following functions.
Ensure that your workspace is empty, use rm(list=ls()).
f <- function() {
x <- 1
y <- 2
c(x, y)
}
f()
rm(f)
If a name isn't defined inside a function, R will look one level up.
x <- 2
y <- 500
g <- function() {
y <- 1
c(x, y)
}
g()
rm(x, g)
The same rules apply if a function is defined inside another function.
x <- 1
y <- 100
h <- function() {
y <- 2
i <- function() {
z <- 3
c(x, y, z)
}
i()
}
h()
rm(x, h)
The same rules apply to closures, functions created by other functions. What do you think this function will return when we call it?
j <- function(x) {
y <- 2
function() {
c(x, y)
}
}
k <- j(1)
k()
rm(j, k)
The same principles apply regardless of the type of associated value - finding functions works exactly the same way as finding variables:
l <- function(x) x + 1
m <- function() {
l <- function(x) x * 2
l(10)
}
m()
rm(l, m)
In the following example n takes on a different value depending on whether R is looking for a function or a variable.
n <- function(x) x / 2
o <- function() {
n <- 10
n(n)
}
o()
rm(n, o)
What happens to the values in between invocations of a function? What will happen the first time you run this function? What will happen the second time?
j <- function() {
if (! exists("a")) {
a <- 1
} else {
a <- a + 1
}
print(a)
}
j()
j()
and now?
a <- 50
j()
j()
rm(list=ls())
A global assignment can be performed with <<-.
If you think you need <<-, think again.
x <- 1
y <- 2
fun <- function () {
x <- 101
y <<- 102
}
fun()
x
y
When calling a function you can specify arguments
Arguments are matched first by exact name (perfect matching), then by prefix matching, and finally by position.
Consider the next function:
f <- function(abcdef, bcde1, bcde2) {
list(a = abcdef, b1 = bcde1, b2 = bcde2)
}
str(f(1, 2, 3))
List of 3
$ a : num 1
$ b1: num 2
$ b2: num 3
Consider the next function:
f <- function(abcdef, bcde1, bcde2) {
list(a = abcdef, b1 = bcde1, b2 = bcde2)
}
str(f(2, 3, abcdef = 1))
List of 3
$ a : num 1
$ b1: num 2
$ b2: num 3
Consider the next function:
f <- function(abcdef, bcde1, bcde2) {
list(a = abcdef, b1 = bcde1, b2 = bcde2)
}
str(f(2, 3, a = 1))
List of 3
$ a : num 1
$ b1: num 2
$ b2: num 3
Consider the next function:
f <- function(abcdef, bcde1, bcde2) {
list(a = abcdef, b1 = bcde1, b2 = bcde2)
}
str(f(1, 3, b = 1))
suma <- function(a, b) a + b
argumentos <- list(a=15, b=5)
do.call(suma, argumentos)
[1] 20
f <- function(a = 1, b = 2) {
c(a, b)
}
f()
[1] 1 2
g <- function(a = 1, b = a * 2) {
c(a, b)
}
g()
g(10)
myhist <- function(x, breaks=length(x)) {
breaks
}
myhist(runif(10))
myhist(runif(10), breaks=501)
Most functions in R are “prefix” operators: the name of the function comes before the arguments.
x <- rnorm(n=1000)
y <- runif(n=1000)
cor(x, y)
You can also create infix functions where the function name comes in between its arguments, like + or -.
All user created infix functions must start and end with %.
R comes with the following infix functions predefined: %%, %*%, %/%, %in%, %o%, %x%.
The complete list of built-in infix operators that don't need % is: ::, :::, $, @, , *, /, +, -, >, >=, <, <=, ==, !=, !, &, &&, |, ||, ~, <-, <<-.
'%+%' <- function(a, b) paste(b, a, sep = " ")
"new" %+% "string"
[1] "string new"
"hello" %+% "my" %+% "world"
[1] "world my hello"
'%+%'('my', 'life')
'%+%'('my', 'life', 'is', 'better')
# Why you obtain an error?
How can you use the infix - as prefix.
'-'(10, 2)
[1] 8
We recommend this references.