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)
cars %>% head()
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1         3.5          1.4         0.2  setosa
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa
# 4          4.6         3.1          1.5         0.2  setosa
# 5          5.0         3.6          1.4         0.2  setosa
# 6          5.4         3.9          1.7         0.4  setosa

Sources

  • Google Developers R Programming Videos
  • Try R