rukÂ·si

# ðŸ“Š R - Functions

Updated at 2017-10-16 19:54

R has three types of functions:

1. Prefix functions: function name goes before arguments, a common function type.
2. Inflix functions: function name goes between arguments, all user-created inflix functions must start and end with `%`.
3. Replacement functions: look like prefix functions but with additional assignment `<-` after the function call, modifying the first argument in-place.

Prefix function examples:

``````# Calling a function.
sum(1, 3, 5)
# [1] 9
``````
``````# Function parameters have names which you can use.
rep("Yo ho!", times = 3)
# [1] "Yo ho!" "Yo ho!" "Yo ho!"
``````

Inflix function example:

```````%+%` <- function(a, b) paste0(a, b)
"new" %+% " string"
# [1] "new string"
``````

Replacement function examples:

```````second<-` <- function(x, value) {
x[2] <- value
return(x)
}
numbers <- 1:3
second(numbers) <- 5
numbers
# [1] 1 5 3

`modify<-` <- function(x, position, value) {
x[position] <- value
return(x)
}
modify(numbers, 1) <- 10
numbers
# [1] 10  5  3
``````

The most important pre-defined functions:

``````# Open manual page of the function
help(sum)

# Prints usage examples
example(sum)

# Prints argument list and their default values.
formals(MyFunction)
# \$x1
#
# \$x2
# [1] 5

# Prints the function body.
body(MyFunction)
# ...

# Prints the environment where the function is defined.
environment(MyFunction)
# <environment: R_GlobalEnv>
``````

Defining functions:

``````MyFunction <- function(x1, x2 = 5) {
if (missing(x1)) {
return(c(0, 0))
}
z1 <- x1 / x1
z2 <- x2 * x2
myvec <- c(z1, z2)
return(myvec)
}

MyFunction(x1 = 2, x2 = 5)
# [1]  1 25
``````

Name your returns if you return more than one value.

``````DivideAndMultiply <- function(x) {
if (missing(x) ) {
stop("Missing x argument.")
}
if (x < 0) {
warning("You are operating with negative numbers.")
}
x1 <- x / 2
x2 <- x * 2
return(list(divided = x1, multiplied = x2))
}

# DivideAndMultiply()
# Would crash in error because of `stop()`

DivideAndMultiply(-5)
# Warning message:
# In DivideAndMultiply(-5) : You are operating with negative numbers.
# ... but the function will still run and return a value

result = DivideAndMultiply(10)

print(result)
# \$divided
# [1] 5
#
# \$multiplied
# [1] 20

print(result\$divided)
# [1] 5

print(result\$multiplied)
# [1] 20
``````

You can use `...` to take in non-specified amount of arguments.

``````Summy <- function(...) {
arguments <- list(...)
return(arguments)
}
Summy(10, 11, 13)
# [[1]]
# [1] 10
#
# [[2]]
# [1] 11
#
# [[3]]
# [1] 13
``````

You can use `invisble` return so that the result can be assigned but is never printed.

``````Summy <- function(...) {
ellipsis.args <- list(...)
invisible(ellipsis.args)
}
Summy(10, 11, 13)
# ... nothing

# You can force an invisible value to be displayed by wrapping it.
a <- 2
# ... nothing
(a <- 2)
# [1] 2
``````

Use `do.call` to call a function with a list of arguments.

``````arguments <- list(1:10, na.rm = TRUE)
do.call(mean, arguments)
# [1] 5.5
``````

__`%>%` pipe operator is not part of base R, it's defined by `magrittr` package. __ Good to understand how it works as it's quite common, basically it sends the left hand side as the first argument to the right hand side.

``````library(magrittr)