R4DS Week 10: What the h*ck is a function?

Introduction

Functions are not always fun

Functions have been the most difficult programming concept for me to grasp, hands down. In almost every class I’ve ever taken, when functions came up I inevitably got lost, frustrated, and quit the class. So if this week’s chapter made you feel like you’ll never understand R, go for a walk, take a deep breath, and come back and work through the exercises here before going back to the section on functions in R for Data Science.

We’re going to ease into functions with the most straightforward examples I could develop, and build on those examples until you’ve had enough practice that you can follow along with this week’s reading.


Functions as recipes

Personally, I like to think of functions like recipes, where your output is your end product, your arguments are your ingredients, and the body (the code inside your function) are the set of instructions you need to follow to get to your end product.

For example, if we were going to make a function for a piece of toast, it might look like this:

toast <- function(bread, butter){
take out one piece of bread, then
toast the bread in the toaster, then
spread 1 TBSP of butter on the bread
}

We can even make this code look a little bit more like R by swapping out our then statements for pipes:

toast <- function(bread, butter){
take out one piece of bread %>%
toast the bread in the toaster %>%
spread 1 TBSP of butter on the bread
}

And if you’re looking for more metaphors, analogies, and/or strategies on ways to think about functions, check out this thread:

This thread has some excellent metaphors and analogies for functions!

Practice Makes Perfect

This next part will be comprised of a series of practice exercises related to functions. Every set of exercises will have four parts:

  1. An example function using text
  2. An example function using addition
  3. An example function using subtraction
  4. Stretch exercises

Run each of the example exercises in RStudio, and then do as many stretch exercises as you need to to feel comfortable with the function. When you’re doing the stretch exercises, it’s OK to take the example exercise and make small modifications to see what changes.


R function practice: mastering the basics

Note that the following functions don’t take any arguments!

### Text-only function example, no arguments:
text_output <- function(){
"Do you like apples?"
}
text_output()

### Addition function example, no arguments:
addition_result <- function(){
20 + 612
}
addition_result()

### Subtraction function example, no arguments:
subtraction_result <- function(){
9283 - 10928
}

Stretch exercises:

  1. In the text-only example, what happens if you remove the quotes from the sentence?
  2. When you run addition_result(), what happens if you leave off the parentheses, and run addition_result?
  3. Create 10 new text functions that take no arguments
  4. Create 10 new addition functions that take no arguments
  5. Create 10 new subtraction functions that take no arguments
  6. Create 10 new functions that combine addition and subtraction and take no arguments
  7. Create 10 new functions that combine several mathematical operators and take no arguments

R function practice: functions that take a single argument

Note that the following functions take a single argument.

### Text-only function example, single argument:
text_single_arg <- function(x){
paste("The", x, "in Spain falls mainly on the plain")
}
text_single_arg("rain")

### Addition function example, single argument:
add_single_arg <- function(y){
y + 22
}
add_single_arg(41)

### Subtraction function example, single argument:
subt_single_arg <- function(z){
98 - z
}
subt_single_arg(12)

Stretch exercises:

  1. In the text-only example, what happens if you do not put the argument “rain” in quotes?
  2. Choose any one of the example functions from above and replace the argument x, y, or z with the word pumpkin. What happens?
  3. Choose any one of the example functions from above and run it without an argument. What happens?
  4. Create 10 new text functions that take a single argument
  5. Create 10 new addition functions that take a single argument
  6. Create 10 new subtraction functions that take a single argument
  7. Create 10 new functions that combine addition and subtraction and take a single argument
  8. Create 10 new functions that combine several mathematical operators and take a single argument

R function practice: functions that take two arguments

Note that the following functions take two arguments.

### Text-only function example, two arguments:
text_two_args <- function(name, state){
paste(name, ", I've a feeling we're not in ", state, " anymore.", sep = "")
}
text_two_args("Toto", "Kansas")

### Addition function example, two arguments:
add_two_args <- function(a, b){
a + 42 + b
}
add_two_args(12, 124)

### Subtraction function example, two arguments:
subt_two_args <- function(x, y){
100 - x - y
}
subt_two_args(100, 100)

Stretch exercises:

  1. Create a text-based function that takes three (or more) arguments
  2. Read up on character strings in R
  3. Create a text-based Madlib in R
  4. Write a function that solves the quadratic equation when given three arguments

My Chemistry Professor’s advice to me, which is now repurposed as my advice to you

When you’re learning, go step-by-step and never take short cuts. Develop a strong foundation now, so that later, when you’re ready, your short cuts are precise and effective.

As you’re learning to program, people are going to want to give you all sorts of advice about how you should do things. We all mean well and have the best of intentions, but sometimes it leads to running in circles rather than progressing with your programming skills.

When you’re learning functions, it’s OK to take more lines than you need to explicitly lay out each step. Sure, we all want to write a beautiful, succinct function that elegantly accomplishes a complex task, but we can save that for later. Right now focus on writing your functions line by line, commenting each line so that you know exactly what’s happening in your function. Do this consistently, and you’ll find that over time your code will evolve to be more concise.