# Load packages
library(tidyverse)
library(tidyquant)
library(moments)
library(ggrepel)
library(scales)
library(stringr)
library(timetk)
library(PerformanceAnalytics)
Functions
# A simple square function example
square_number <- function(x) {
x * x
}
square_number(5)
## [1] 25
When should you write a function
# Create a reproducible dataset
set.seed(1234)
df <- tibble(
a = rnorm(10),
b = rnorm(10),
c = rnorm(10),
d = rnorm(10)
)
# Rescale function to avoid repeating code
rescale_vec <- function(x) {
(x - min(x)) / (max(x) - min(x))
}
# Apply the function to each column
df$a <- rescale_vec(df$a)
df$b <- rescale_vec(df$b)
df$c <- rescale_vec(df$c)
df$d <- rescale_vec(df$d)
df
## # A tibble: 10 × 4
## a b c d
## <dbl> <dbl> <dbl> <dbl>
## 1 0.332 0.153 0.782 1
## 2 0.765 0 0.473 0.519
## 3 1 0.0651 0.498 0.448
## 4 0 0.311 0.943 0.511
## 5 0.809 0.573 0.373 0.168
## 6 0.831 0.260 0 0.308
## 7 0.516 0.143 1 0
## 8 0.524 0.0255 0.210 0.256
## 9 0.519 0.0472 0.708 0.575
## 10 0.424 1 0.253 0.522
Functions are for humans and computers
# Bad vs. good function naming
add_vals <- function(x, y) {
x + y
}
add_vals(3, 5)
## [1] 8
Conditional execution
# Define function that uses if, else if, and stop
detect_sign <- function(x) {
if (x > 0) {
message("Value is positive")
print(x)
} else if (x == 0) {
warning("Value is zero, but acceptable")
print(x)
} else {
stop("Value is negative. Stopping function.")
}
}
# Safe test
detect_sign(3)
## [1] 3
# Warning test
detect_sign(0)
## [1] 0
# Error test — comment this line before knitting!
# detect_sign(-1)
Function arguments
# Example vector with NA and outlier
x <- c(1:10, 100, NA)
# Custom wrapper for mean()
mean_remove_na <- function(x, na.rm = TRUE, ...) {
mean(x, na.rm = na.rm, ...)
}
# Run examples
mean_remove_na(x)
## [1] 14.09091
mean_remove_na(x, na.rm = FALSE) # Returns NA
## [1] NA
mean_remove_na(x, trim = 0.1) # Trims outlier
## [1] 6