Learning Objectives

General Instructions


1) Example: Fahrenheit to Celsius

Let’s consider a typical programming example that involves converting fahrenheit degrees into celsius degrees. The conversion formula is

\[ (F - 32) \times 5/9 = C \]

Here’s some R code to convert 100 fahrenheit degrees into Celsius degrees:

# fahrenheit degrees
fahr_deg = 100

# convert to celsius
(fahr_deg - 32) * (5/9)
## [1] 37.77778

What if you want to conver 90 fahrenheit degrees in Celsius degrees? One option would be to rewrite the previous lines as:

# 90 fahrenheit degrees to celsius
fahr_deg = 90
(fahr_deg - 32) * (5/9)
## [1] 32.22222

However, retyping many lines of code can be very boring, tedious, and inefficient. To make your code reusable in a more efficient manner, you will have to write functions.

Writing a simple function

Step 1: write code for a small and concrete example, and make sure that it works.

Step 2: encapsulate the code in the form of a function. You have to choose a name, some argument(s), and determine the output.

Here’s one example with a function fahrenheit_to_celsius(). You should always document your functions using the comments

#title

#description

#inputs (list each input separately)

#output

as shown in this example.

# title: farenheit celsius function
# description: converts farenheit to celsius
# inputs:
# - x: the farenheit value
# output:
# - computed celsius value
fahrenheit_to_celsius <- function(x) {
  (x - 32) * (5/9)
}

fahrenheit_to_celsius(100)
## [1] 37.77778

If you want to get the conversion of 90 fahrenheit degrees, you just simply execute it again by changing its argument:

fahrenheit_to_celsius(90)
## [1] 32.22222

And because we are using arithmetic operators (i.e. multiplication, subtraction, division), the function is also vectorized:

fahrenheit_to_celsius(c(90, 100, 110))
## [1] 32.22222 37.77778 43.33333

Sometimes it is recommended to give a default value to one (or more) of the arguments. In this case, we can give a default value of x = 1. When the user executes the function without any input, fahrenheit_to_celsius returns the value of 1 fahrenheit degree to Celsius degrees:

fahrenheit_to_celsius <- function(x = 1) {
  (x - 32) * (5/9)
}

# default execution
fahrenheit_to_celsius()
## [1] -17.22222

2) Converting miles to kilometers

Write a function miles2kms() that converts miles into kilometers: 1 mile is equal to 1.6 kilometers. Give the argument a default value of 1. Include comments to document your function.

#title: miles to kilometers function
#description: converts miles to kilometers
#inputs:
# - x the mile value
#output:
# - kilometers value
miles2kms <- function(x = 1) {
  (x) * (1.6)
}

3) Converting seconds to years

According to Wikipedia, in 2015 the life expectancy of a person born in the US was 79 years. Consider the following question: Can a newborn baby in USA expect to live for one billion (\(10^9\)) seconds?

To answer this question, write a function seconds2years() that takes a number in seconds and returns the equivalent number of years. Include comments to document your function. Test the function with seconds2years(1000000000)

#title: seconds to years functions
#description: converts seconds to years
#inputs:
# - x the second value
#output:
# - years value
seconds2years <- function(x = 1) {
  (x) / (3.154e+7)
}
seconds2years(1000000000)
## [1] 31.70577

4) Simple Math Functions

Consider the following mathematical functions:

\[ f(x) = x^2, \qquad g(x) = 2x + 5 \]

Write two functions f() and g() based on the previous equations. Include comments to document your function.

#title: x squared function
#description: squares the value x
#inputs:
# - x 
#output:
# - x squared
f <- function(x = 1) {
  (x)^2
}
#title: random function
#description: multiplies x by 2 and adds 5
#inputs:
# - x 
#output:
# - 2x+5
g <- function(x = 1) {
  2*(x)+ 5
}


Test your functions with:

f(2)
## [1] 4
f(-5)
## [1] 25
g(0)
## [1] 5
g(-5/2)
## [1] 0

Write code to create the following composite functions. Include comments to document your function.

# your function fog()
#title: f of g
#description: inputs x into g then inputs the result into f
#inputs:
# - x 
#output:
# - f(g(x))
fog <- function(x=1){
  f(g(x))
}
# your function gof()
#title: g of g
#description: inputs x into f then inputs the result into g
#inputs:
# - x 
#output:
# - g(f(x))
gof <- function(x=1){
  g(f(x))
}

Test your composite functions with:

fog(2)
## [1] 81
fog(-5)
## [1] 25
gof(0)
## [1] 5
gof(-5/2)
## [1] 17.5

5) Pythagoras

The pythagoras formula is used to compute the length of the hypotenuse, \(c\), of a right triangle with legs of length \(a\) and \(b\).

\[ c = \sqrt{a^2 + b^2} \]

5.1) pythagoras() version 1

Write a function pythagoras() that takes two arguments a and b, and returns the length of the hypotenuse. Don’t forget to include comments to document your function!

Test your pythagoras() with two leg values: pythagoras(3, 4)

# your pythogras function
#title: Pythagorean theorem 
#description: inputs a and b, squares a and b, sums the result and takes the square root of that result
#inputs:
# - a and b
#output:
# - sqrt(a^2+b^2)
pythagoras <- function(a=1, b=1){
  sqrt(((a)^2) + ((b)^2))
}

5.2) pythagoras() version 2

Modify your function pythagoras() so that argument b takes the same value of argument a. Include comments to document your function. Test it with just one leg value: pythagoras(5)

# your modified pythogras function
# your pythogras function
#title: Pythagorean theorem 
#description: inputs a and a, squares a and a, sums the result and takes the square root of that result
#inputs:
# - a and a
#output:
# - sqrt(a^2+a^2)
pythagoras <- function(a=1){
  sqrt(((a)^2) + ((a)^2))
}

6) Polynomials

In this problem we want to see whether the graph of a given polynomial will cross or touch the x axis in a given interval.

Let’s begin with the polynomial:

\[ f(x) = x^2 - 1 \]

The first thing to do is write a function for the polynomial, for instance:

poly1 <- function(x) {
  x^2 - 1
}

Once you have a function for the polynomial, you can create a set of pairs of points \(x\) and \(y = f(x)\), and then use them to graph the polynomial

# set of points
x <- seq(-4, 4, length.out = 50)
y <- poly1(x)

# graph polynomial
plot(x, y, type = 'l', lwd = 3, col = "#FB7215", las = 1)
abline(h = 0, v = 0, col = '#888888aa', lwd = 1.5)
title(main = expression(paste(f(x), ' = ', x^2, (x - 1))))

Write functions and graph the following polynomials in the x-axis interval -4 to 4. Include comments to document your function:

  1. \(f(x) = x^3\)
# your code
#title: x cubed 
#description: inputs x
#inputs:
# - x
#output:
# - x^3
polya <- function(x) {
  x^3
}

# set of points
x <- seq(-4, 4, length.out = 50)
y <- polya(x)

# graph polynomial
plot(x, y, type = 'l', lwd = 3, col = "#FB7215", las = 1)
abline(h = 0, v = 0, col = '#888888aa', lwd = 1.5)
title(main = expression(paste(f(x), ' = ', x^3)))

  1. \(f(x) = (x^2 - 1)(x + 3)^3\)
# your code
# title: random function
# description: inputs x
# inputs:
# - x
# output:
# - (x^2 - 1)(x + 3)^3
polyb <- function(x){
  ((x^2) - 1)*((x) + 3)^3
}

# set of points
x <- seq(-4, 4, length.out = 50)
y <- polyb(x)

# graph polynomial
plot(x, y, type = 'l', lwd = 3, col = "#FB7215", las = 1)
abline(h = 0, v = 0, col = '#888888aa', lwd = 1.5)
title(main = expression(paste(f(x), ' = ',(x^2 - 1)(x + 3)^3)))

  1. \(f(x) = (x^2 - 1)(x^2 - 9)\)
# your code
# title: random function
# description: inputs x
# inputs:
# - x
# output:
# - (x^2 - 1)(x^2 - 9)
polyc <- function(x){
  (x^2 - 1)*(x^2 - 9)
}

# set of points
x <- seq(-4, 4, length.out = 50)
y <- polyc(x)

# graph polynomial
plot(x, y, type = 'l', lwd = 3, col = "#FB7215", las = 1)
abline(h = 0, v = 0, col = '#888888aa', lwd = 1.5)
title(main = expression(paste(f(x), ' = ',(x^2 - 1)(x^2 - 9))))