R/K13_functions.R

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

  # To complete this assignment, edit this R script inside the brackets for
  # question 1, for example: between #1@ and @#1. Un-comment the line to make it
  # live code instead of a comment (Ctrl Shift C on Windows; Cmd Shift C on Macs),
  # save your progress (Ctrl/Cmd S), execute the code in the console (put your
  # cursor in the piece of code and hit Ctrl/Cmd Return), and test your answer by
  # running the test file (Ctrl/Cmd Shift T). When you've passed all tests, compile
  # ("knit") the script to html (Ctrl/Cmd Shift K) and turn the html file in on
  # Canvas.

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

  # 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.
}
cobriant/tidyverse_koans documentation built on March 31, 2024, 8:34 a.m.