1 Class Overview

This final class has two main parts:

  1. A short 30-minute review of essential R concepts.
  2. A hands-on introduction to writing functions in R, using mathematical plotting applications.

A suggested class structure is:

  • First 30 minutes: Review essential R concepts.
  • Next 35–45 minutes: Write and use mathematical functions.
  • Final 10–15 minutes: Student exercise and course wrap-up.

2 Part 1: Thirty-Minute R Review

2.1 1. Objects, Vectors, and Calculations

# Creating objects
x <- 10
y <- 4

x + y
## [1] 14
x - y
## [1] 6
x * y
## [1] 40
x / y
## [1] 2.5
x^2
## [1] 100
sqrt(x)
## [1] 3.162278
# Creating a vector
numbers <- c(3, 7, 2, 9, 5)

length(numbers)
## [1] 5
sum(numbers)
## [1] 26
mean(numbers)
## [1] 5.2
min(numbers)
## [1] 2
max(numbers)
## [1] 9

2.1.1 Vector Indexing

numbers[2]
## [1] 7
numbers[2:4]
## [1] 7 2 9
numbers[numbers > 5]
## [1] 7 9

2.2 2. Sequences and Missing Values

x <- seq(from = 0, to = 10, by = 2)
x
## [1]  0  2  4  6  8 10
y <- c(5, 8, NA, 12, 4)

mean(y)
## [1] NA
mean(y, na.rm = TRUE)
## [1] 7.25
is.na(y)
## [1] FALSE FALSE  TRUE FALSE FALSE
y[!is.na(y)]
## [1]  5  8 12  4

Do not use the following expression to identify missing values:

y == NA

Use:

is.na(y)
## [1] FALSE FALSE  TRUE FALSE FALSE

2.3 3. Data Frames

students <- data.frame(
  name = c("Ali", "Sara", "John", "Maria"),
  midterm = c(75, 82, 68, 91),
  final = c(80, 88, 74, 94)
)

students
##    name midterm final
## 1   Ali      75    80
## 2  Sara      82    88
## 3  John      68    74
## 4 Maria      91    94
str(students)
## 'data.frame':    4 obs. of  3 variables:
##  $ name   : chr  "Ali" "Sara" "John" "Maria"
##  $ midterm: num  75 82 68 91
##  $ final  : num  80 88 74 94
summary(students)
##      name              midterm          final     
##  Length:4           Min.   :68.00   Min.   :74.0  
##  Class :character   1st Qu.:73.25   1st Qu.:78.5  
##  Mode  :character   Median :78.50   Median :84.0  
##                     Mean   :79.00   Mean   :84.0  
##                     3rd Qu.:84.25   3rd Qu.:89.5  
##                     Max.   :91.00   Max.   :94.0

2.3.1 Selecting Variables and Rows

students$midterm
## [1] 75 82 68 91
students[students$final >= 80, ]
##    name midterm final
## 1   Ali      75    80
## 2  Sara      82    88
## 4 Maria      91    94

2.3.2 Creating a New Variable

students$average <- (students$midterm + students$final) / 2
students
##    name midterm final average
## 1   Ali      75    80    77.5
## 2  Sara      82    88    85.0
## 3  John      68    74    71.0
## 4 Maria      91    94    92.5

2.4 4. Conditions and Loops

2.4.1 A Function with Conditional Statements

grade_letter <- function(mark) {
  if (mark >= 90) {
    return("A")
  } else if (mark >= 80) {
    return("B")
  } else if (mark >= 70) {
    return("C")
  } else if (mark >= 60) {
    return("D")
  } else {
    return("F")
  }
}

grade_letter(84)
## [1] "B"

2.4.2 A Simple Loop

for (i in c(1,7,4)) {
  print(i^2)
}
## [1] 1
## [1] 49
## [1] 16

In many cases, vectorized R code is shorter and more efficient:

(1:5)^2
## [1]  1  4  9 16 25

2.5 5. Basic Plots

x <- seq(-5, 5, length.out = 200)
y <- x^2

plot(
  x,
  y,
  type = "l",
  lwd = 2,
  main = "The Function y = x^2",
  xlab = "x",
  ylab = "y"
)

abline(h = 0, v = 0, lty = 2)

Common values for the type argument include:

plot(x, y, type = "p")  # Points
plot(x, y, type = "l")  # Lines
plot(x, y, type = "b")  # Both points and lines

2.6 6. Rapid Review Challenge

Consider the following vector:

values <- c(12, 7, 15, NA, 9, 20, 4)

Complete the following tasks:

  1. Calculate the mean while ignoring the missing value.
  2. Select values greater than 10.
  3. Calculate the square of each non-missing value.
  4. Plot the non-missing values.

2.6.1 Solution

mean(values, na.rm = TRUE)
## [1] 11.16667
values[values > 10 & !is.na(values)]
## [1] 12 15 20
values[!is.na(values)]^2
## [1] 144  49 225  81 400  16
clean_values <- values[!is.na(values)]

plot(
  clean_values,
  type = "b",
  main = "Non-Missing Values",
  xlab = "Index",
  ylab = "Value"
)

3 Part 2: Writing Functions in R

3.1 Learning Objectives

By the end of this section, students should be able to:

  1. Explain the components of an R function.
  2. Write a function with arguments and default values.
  3. Call a function using different inputs.
  4. Write a function that evaluates and plots a mathematical expression.

3.2 1. General Structure of an R Function

The general structure of a function is:

function_name <- function(arguments) {
  # Commands
  result <- ...
  return(result)
}

The main components are:

  • The function name
  • The input arguments
  • The function body
  • The returned result

3.3 2. A Simple Mathematical Function

Define a function that calculates the square of a number:

square <- function(x) {
  result <- x^2
  return(result)
}

Test the function:

square(4)
## [1] 16
square(-3)
## [1] 9
square(c(1, 2, 3, 4))
## [1]  1  4  9 16

R automatically returns the result of the last evaluated expression. Therefore, the same function can be written more compactly:

square <- function(x) {
  x^2
}

3.4 3. Writing a Linear Function

A linear function has the form

\[ f(x) = mx + b. \]

Define it in R:

linear_function <- function(x, m = 1, b = 0) {
  m * x + b
}

Test the function:

linear_function(x = 3)
## [1] 3
linear_function(
  x = 3,
  m = 2,
  b = 5
)
## [1] 11
linear_function(
  x = c(-2, -1, 0, 1, 2),
  m = 2,
  b = 1
)
## [1] -3 -1  1  3  5

3.4.1 Plotting a Linear Function

x <- seq(-5, 5, length.out = 200)
y <- linear_function(x, m = 2, b = 1)

plot(
  x,
  y,
  type = "l",
  lwd = 2,
  main = "Linear Function: f(x) = 2x + 1",
  xlab = "x",
  ylab = "f(x)"
)

abline(h = 0, v = 0, lty = 2)

3.5 4. Writing a Quadratic Function

A quadratic function has the form

\[ f(x) = ax^2 + bx + c. \]

quadratic <- function(x, a = 1, b = 0, c = 0) {
  a * x^2 + b * x + c
}

Test the function:

quadratic(2)
## [1] 4
quadratic(
  x = 2,
  a = 1,
  b = -2,
  c = -3
)
## [1] -3

3.5.1 Plotting a Quadratic Function

x <- seq(-5, 5, length.out = 400)
y <- quadratic(x, a = 1, b = -2, c = -3)

plot(
  x,
  y,
  type = "l",
  lwd = 2,
  main = "Quadratic Function",
  xlab = "x",
  ylab = "f(x)"
)

abline(h = 0, v = 0, lty = 2)

points(
  x = c(-1, 3),
  y = c(0, 0),
  pch = 19
)

The plotted function is

\[ f(x) = x^2 - 2x - 3, \]

with roots \(x=-1\) and \(x=3\).

4 Part 3: A General Function-Plotting Function

We now combine R functions and mathematical functions.

plot_function <- function(
  fun,
  lower = -5,
  upper = 5,
  n = 400,
  main = "Graph of a Mathematical Function",
  xlab = "x",
  ylab = "f(x)"
) {

  if (!is.function(fun)) {
    stop("'fun' must be an R function.")
  }

  if (lower >= upper) {
    stop("'lower' must be smaller than 'upper'.")
  }

  if (n < 2) {
    stop("'n' must be at least 2.")
  }

  x <- seq(
    from = lower,
    to = upper,
    length.out = n
  )

  y <- fun(x)

  plot(
    x,
    y,
    type = "l",
    lwd = 2,
    main = main,
    xlab = xlab,
    ylab = ylab
  )

  abline(
    h = 0,
    v = 0,
    lty = 2
  )

  invisible(
    data.frame(
      x = x,
      y = y
    )
  )
}

4.1 Example 1: Quadratic Function

plot_function(
  fun = function(x) x^2 - 4,
  lower = -4,
  upper = 4,
  main = "f(x) = x^2 - 4"
)

4.2 Example 2: Cubic Function

plot_function(
  fun = function(x) x^3 - 3 * x,
  lower = -3,
  upper = 3,
  main = "f(x) = x^3 - 3x"
)

4.3 Example 3: Sine Function

plot_function(
  fun = sin,
  lower = -2 * pi,
  upper = 2 * pi,
  main = "f(x) = sin(x)"
)

4.4 Example 4: Exponential Decay

plot_function(
  fun = function(x) exp(-x),
  lower = 0,
  upper = 5,
  main = "f(x) = exp(-x)"
)

4.5 Example 5: Bell-Shaped Function

plot_function(
  fun = function(x) exp(-x^2),
  lower = -3,
  upper = 3,
  main = "f(x) = exp(-x^2)"
)

5 Part 4: Student Activity

Write an R function for

\[ f(x) = ax^3 + bx^2 + cx + d. \]

5.1 Starter Code

cubic <- function(x, a, b, c, d) {
  # Complete this function
}

5.2 Solution

cubic <- function(x, a = 1, b = 0, c = 0, d = 0) {
  a * x^3 + b * x^2 + c * x + d
}

Test the function:

cubic(
  x = 2,
  a = 1,
  b = -2,
  c = 1,
  d = 3
)
## [1] 5

Plot the function:

plot_function(
  fun = function(x) {
    cubic(
      x,
      a = 1,
      b = -2,
      c = -1,
      d = 2
    )
  },
  lower = -3,
  upper = 4,
  main = "A Cubic Function"
)

6 Part 5: Optional Calculus Application

A numerical approximation to the derivative of a function is

\[ f'(x) \approx \frac{f(x+h)-f(x-h)}{2h}. \]

6.1 Numerical Derivative Function

numerical_derivative <- function(fun, x, h = 0.0001) {

  if (!is.function(fun)) {
    stop("'fun' must be a function.")
  }

  if (h <= 0) {
    stop("'h' must be positive.")
  }

  (fun(x + h) - fun(x - h)) / (2 * h)
}

For \(f(x)=x^2\), the exact derivative is \(f'(x)=2x\).

f <- function(x) {
  x^2
}

numerical_derivative(
  fun = f,
  x = 3
)
## [1] 6

The result should be approximately 6.

6.2 Plotting a Function and Its Numerical Derivative

x <- seq(-4, 4, length.out = 300)

y <- f(x)
dy <- numerical_derivative(f, x)

plot(
  x,
  y,
  type = "l",
  lwd = 2,
  ylim = range(c(y, dy)),
  main = "A Function and Its Numerical Derivative",
  xlab = "x",
  ylab = "Value"
)

lines(
  x,
  dy,
  lwd = 2,
  lty = 2
)

abline(
  h = 0,
  v = 0,
  lty = 3
)

legend(
  "top",
  legend = c(
    "f(x) = x^2",
    "Approximate derivative"
  ),
  lty = c(1, 2),
  lwd = 2
)

7 Final Exit Question

Write and plot the function

\[ f(x) = \cos(x) + \frac{x}{5}, \qquad -2\pi \leq x \leq 2\pi. \]

7.1 Solution

final_function <- function(x) {
  cos(x) + x / 5
}

plot_function(
  fun = final_function,
  lower = -2 * pi,
  upper = 2 * pi,
  main = "f(x) = cos(x) + x/5"
)

8 Summary

This lesson combines the main R skills covered in the course:

  • Creating and manipulating objects
  • Working with vectors
  • Handling missing values
  • Using data frames
  • Writing conditional statements
  • Using loops and vectorization
  • Producing basic plots
  • Writing reusable functions
  • Passing functions as arguments
  • Applying R to introductory mathematical problems