function() {#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  #                   Intro to the Tidyverse by Colleen O'Briant
  #                           Koan #13: Custom Functions
  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # In order to progress:
  # 1. Read all instructions carefully.
  # 2. When you come to an exercise, fill in the blank, un-comment the line
  #    (Ctrl/Cmd Shift C), and execute the code in the console (Ctrl/Cmd Return).
  #    If the piece of code spans multiple lines, highlight the whole chunk or
  #    simply put your cursor at the end of the last line.
  # 3. Save (Ctrl/Cmd S).
  # 4. Test that your answers are correct (Ctrl/Cmd Shift T).

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # In this koan you'll learn how to write your own custom functions in R.

  # So far, we've learned about a lot of great functions that make data analysis
  # easy. For example, all these are functions:
  # 'sum()', 'mean()', 'qplot()', 'lm()', 'ggplot()', 'filter()', 'summarize()'

  # Functions take arguments as inputs, perform an action in the body, and
  # produce some output at the end. If you're having trouble using a function
  # from the tidyverse, it's probably because there's something about the
  # function's arguments, body, or output that you're not understanding.

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # Run this code to get started:
  library(tidyverse)
  library(gapminder)

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  #                        ----- Defining a function -----

  # This is the format for defining a function in R:

  # my_function <- function(arg1, arg2, arg3) {
  #     body
  #     return(output)
  # }

  # 'my_function' is the name of the function. You can call your functions
  # (almost) anything you'd like. Names can have letters, numbers, periods, and
  # underscores, but they should always start with a letter. It's also good
  # practice to avoid using common names for your functions so that your
  # functions have unique names. That is, if you plan on using 'dplyr::filter',
  # don't create a function named 'filter'. And if you plan on using 'c()' to
  # create a vector, don't name anything else 'c'.

  # 'arg1', 'arg2', and 'arg3' are the function arguments. You can have any
  # number of arguments, including zero.

  # 'body' defines the action that the function takes.

  # 'output' is the output of the function.

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # Example: this is a function that adds two numbers.

  plus <- function(a, b) {
    return(a + b)
  }

  plus(5, 3)

  # 1. Does it work on numbers? Fill in the blanks to make the code return -----
  # TRUE.

  #1@

  # plus(__, __) == 3

  #@1


  # 2. Does it work on vectors? ------------------------------------------------

  #2@

  # plus(__, __) == c(4, 0, 1)

  #@2

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # 3. Write a function that takes one argument as the input and returns -------
  # its square. So for example, 'square(6)' will return 36. You can name the
  # argument anything you want (x, y, arg1, etc), as long as you're consistent.

  #3@

  # square <- function(__) {
  #   __
  # }

  #@3


  # 4. Does it work on numbers? ------------------------------------------------

  #4@

  # square(__) == 16

  #@4


  # 5. Does it work on vectors? ------------------------------------------------

  #5@

  # square(__) == c(1, 4, 9)

  #@5


  # 6. Test that it works inside 'mutate()': Take 'gapminder' and add a new ----
  # variable 'gdpPercap_squared' that is the square of the gdpPercap variable,
  # using your function 'square'.

  #6@

  # __

  #@6

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # If you aren't explicit about what you want the output of your function to
  # be by using 'return()', R will automatically return the last thing it
  # evaluated. So in our simple 'plus' function, we can simply define it as:

  plus <- function(a, b) {
    a + b
  }

  plus(2, 3)

  # Note that this will also output a + b, because a + b was the last thing the
  # function evaluated:

  plus <- function(a, b) {
    a - b
    a + b
  }

  plus(2, 3)

  # To get your function to output multiple values, you'll need to return a
  # vector:

  plus_minus <- function(a, b) {
    c(a - b, a + b)
  }

  plus_minus(5, 2)

  # 7. Your turn: write a function that takes zero arguments and returns -------
  # the number 1 and also a number drawn from N(1, 1).

  #7@

  # ones <- function() {
  #   __
  # }

  # ones()

  #@7

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # Your custom functions can output anything: a value, a vector, a tibble,
  # another function, and even a plot! Here's a function called 'scatterplot'
  # that outputs a ggplot with geom_point(). The curly braces that wrap 'xaxis'
  # and 'yaxis' will be explained in the next koan.

  scatterplot <- function(tibble, xaxis, yaxis) {
    ggplot(data = tibble, aes(x = {{ xaxis }}, y = {{ yaxis }})) +
      geom_point()
  }

  # 8. Test that 'scatterplot' works using 'gapminder', 'gdpPercap' ------------
  # on the x-axis, and 'lifeExp' on the y-axis.

  #8@

  # scatterplot(__, __, __)

  #@8


  #                           ----- Default Values -----

  # Lastly, I want to mention that function arguments can have default values.
  # For instance, geom_point() dots have 'color = black' if you don't change the
  # color. And the geom_smooth() line is blue by default. Suppose I want my
  # points in my scatterplot to be pink by default. Here's how I can do that:

  scatter_pink <- function(tibble, xaxis, yaxis, point_color = "pink") {
    ggplot(data = tibble, aes(x = {{ xaxis }}, y = {{ yaxis }})) +
      geom_point(color = point_color)
  }

  # If I don't declare a point_color, my scatterplot ends up being pink:

  scatter_pink(gapminder, gdpPercap, lifeExp)

  # But if I do declare a point_color, my scatterplot becomes that color.

  # 9. Use 'scatter_pink' to draw a gapminder scatterplot with *blue* ----------
  # points.

  #9@

  # scatter_pink(__, __, __, __)

  #@9

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # Great work! You're one step closer to tidyverse enlightenment. Make sure to
  # return to this topic to meditate on it later.
}
## function() {#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
##   #                   Intro to the Tidyverse by Colleen O'Briant
##   #                           Koan #13: Custom Functions
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # In order to progress:
##   # 1. Read all instructions carefully.
##   # 2. When you come to an exercise, fill in the blank, un-comment the line
##   #    (Ctrl/Cmd Shift C), and execute the code in the console (Ctrl/Cmd Return).
##   #    If the piece of code spans multiple lines, highlight the whole chunk or
##   #    simply put your cursor at the end of the last line.
##   # 3. Save (Ctrl/Cmd S).
##   # 4. Test that your answers are correct (Ctrl/Cmd Shift T).
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # In this koan you'll learn how to write your own custom functions in R.
## 
##   # So far, we've learned about a lot of great functions that make data analysis
##   # easy. For example, all these are functions:
##   # 'sum()', 'mean()', 'qplot()', 'lm()', 'ggplot()', 'filter()', 'summarize()'
## 
##   # Functions take arguments as inputs, perform an action in the body, and
##   # produce some output at the end. If you're having trouble using a function
##   # from the tidyverse, it's probably because there's something about the
##   # function's arguments, body, or output that you're not understanding.
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # Run this code to get started:
##   library(tidyverse)
##   library(gapminder)
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   #                        ----- Defining a function -----
## 
##   # This is the format for defining a function in R:
## 
##   # my_function <- function(arg1, arg2, arg3) {
##   #     body
##   #     return(output)
##   # }
## 
##   # 'my_function' is the name of the function. You can call your functions
##   # (almost) anything you'd like. Names can have letters, numbers, periods, and
##   # underscores, but they should always start with a letter. It's also good
##   # practice to avoid using common names for your functions so that your
##   # functions have unique names. That is, if you plan on using 'dplyr::filter',
##   # don't create a function named 'filter'. And if you plan on using 'c()' to
##   # create a vector, don't name anything else 'c'.
## 
##   # 'arg1', 'arg2', and 'arg3' are the function arguments. You can have any
##   # number of arguments, including zero.
## 
##   # 'body' defines the action that the function takes.
## 
##   # 'output' is the output of the function.
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # Example: this is a function that adds two numbers.
## 
##   plus <- function(a, b) {
##     return(a + b)
##   }
## 
##   plus(5, 3)
## 
##   # 1. Does it work on numbers? Fill in the blanks to make the code return -----
##   # TRUE.
## 
##   #1@
## 
##   # plus(__, __) == 3
## 
##   #@1
## 
## 
##   # 2. Does it work on vectors? ------------------------------------------------
## 
##   #2@
## 
##   # plus(__, __) == c(4, 0, 1)
## 
##   #@2
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # 3. Write a function that takes one argument as the input and returns -------
##   # its square. So for example, 'square(6)' will return 36. You can name the
##   # argument anything you want (x, y, arg1, etc), as long as you're consistent.
## 
##   #3@
## 
##   # square <- function(__) {
##   #   __
##   # }
## 
##   #@3
## 
## 
##   # 4. Does it work on numbers? ------------------------------------------------
## 
##   #4@
## 
##   # square(__) == 16
## 
##   #@4
## 
## 
##   # 5. Does it work on vectors? ------------------------------------------------
## 
##   #5@
## 
##   # square(__) == c(1, 4, 9)
## 
##   #@5
## 
## 
##   # 6. Test that it works inside 'mutate()': Take 'gapminder' and add a new ----
##   # variable 'gdpPercap_squared' that is the square of the gdpPercap variable,
##   # using your function 'square'.
## 
##   #6@
## 
##   # __
## 
##   #@6
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # If you aren't explicit about what you want the output of your function to
##   # be by using 'return()', R will automatically return the last thing it
##   # evaluated. So in our simple 'plus' function, we can simply define it as:
## 
##   plus <- function(a, b) {
##     a + b
##   }
## 
##   plus(2, 3)
## 
##   # Note that this will also output a + b, because a + b was the last thing the
##   # function evaluated:
## 
##   plus <- function(a, b) {
##     a - b
##     a + b
##   }
## 
##   plus(2, 3)
## 
##   # To get your function to output multiple values, you'll need to return a
##   # vector:
## 
##   plus_minus <- function(a, b) {
##     c(a - b, a + b)
##   }
## 
##   plus_minus(5, 2)
## 
##   # 7. Your turn: write a function that takes zero arguments and returns -------
##   # the number 1 and also a number drawn from N(1, 1).
## 
##   #7@
## 
##   # ones <- function() {
##   #   __
##   # }
## 
##   # ones()
## 
##   #@7
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # Your custom functions can output anything: a value, a vector, a tibble,
##   # another function, and even a plot! Here's a function called 'scatterplot'
##   # that outputs a ggplot with geom_point(). The curly braces that wrap 'xaxis'
##   # and 'yaxis' will be explained in the next koan.
## 
##   scatterplot <- function(tibble, xaxis, yaxis) {
##     ggplot(data = tibble, aes(x = {{ xaxis }}, y = {{ yaxis }})) +
##       geom_point()
##   }
## 
##   # 8. Test that 'scatterplot' works using 'gapminder', 'gdpPercap' ------------
##   # on the x-axis, and 'lifeExp' on the y-axis.
## 
##   #8@
## 
##   # scatterplot(__, __, __)
## 
##   #@8
## 
## 
##   #                           ----- Default Values -----
## 
##   # Lastly, I want to mention that function arguments can have default values.
##   # For instance, geom_point() dots have 'color = black' if you don't change the
##   # color. And the geom_smooth() line is blue by default. Suppose I want my
##   # points in my scatterplot to be pink by default. Here's how I can do that:
## 
##   scatter_pink <- function(tibble, xaxis, yaxis, point_color = "pink") {
##     ggplot(data = tibble, aes(x = {{ xaxis }}, y = {{ yaxis }})) +
##       geom_point(color = point_color)
##   }
## 
##   # If I don't declare a point_color, my scatterplot ends up being pink:
## 
##   scatter_pink(gapminder, gdpPercap, lifeExp)
## 
##   # But if I do declare a point_color, my scatterplot becomes that color.
## 
##   # 9. Use 'scatter_pink' to draw a gapminder scatterplot with *blue* ----------
##   # points.
## 
##   #9@
## 
##   # scatter_pink(__, __, __, __)
## 
##   #@9
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # Great work! You're one step closer to tidyverse enlightenment. Make sure to
##   # return to this topic to meditate on it later.
## }