#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# Intro to the Tidyverse by Colleen O'Briant
# Koan #4: filter, select, and mutate
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# 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 the first three dplyr verbs: 'filter', 'select',
# and 'mutate'.
# dplyr is a package for data manipulation (the name is supposed to evoke
# "data pliers"). It's included in the tidyverse, so you automatically have
# access to all the dplyr functions whenever you attach the tidyverse with
# 'library(tidyverse)'.
# dplyr is a SQL implementation. What is SQL? It stands for "Structured Query
# Language": it's a programming language for answering questions ("queries")
# about a dataset. With SQL (and with dplyr), you can transform your data into a
# neat table of results to answer just about any question you have about your
# data!
# As we'll see in this exercise and the next, you can use dplyr on a
# basic demographic dataset to answer questions like...
# - What were the 5 richest countries in the 1950s?
# - Which continent has the highest life expectancy on average?
# - What year did Mexico have the highest population growth?
# SQL is wonderful because in order to answer all these questions, you only need
# to learn 7 functions! dplyr is the same way, except dplyr is EVEN MORE
# wonderful because, where SQL is very *structured*, dplyr is not. You can use
# the 7 dplyr functions in whichever order feels straightforward and logical.
# This helps with readability and clarity (two of our biggest goals with writing
# good code).
# In this exercise, we'll learn the first 3 dplyr functions: 'filter()',
# 'select()', and 'mutate()'.
# In the next exercise, we'll learn two more: 'summarize()' and 'group_by()'.
# Finally, we'll finish up by learning the last two: 'arrange()' and 'slice()'.
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# Run this code to get started and to view the dataset:
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✔ ggplot2 3.3.6 ✔ purrr 0.3.4
## ✔ tibble 3.1.7 ✔ dplyr 1.0.9
## ✔ tidyr 1.2.0 ✔ stringr 1.4.0
## ✔ readr 2.1.2 ✔ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
# Un-comment the next line to install a new package 'gapminder', then re-comment
# it so you don't keep installing it every time you run this script or test
# this koan.
# install.packages("gapminder")
library(gapminder)
# view(gapminder)
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# ----- filter() -----
# The first dplyr function we'll learn is 'filter()'. It lets us filter
# our tibble by some logical condition, like "continent is equal to Europe".
# This gives us all the rows (observations) that have Europe as the continent.
gapminder %>%
filter(continent == "Europe")
## # A tibble: 360 × 6
## country continent year lifeExp pop gdpPercap
## <fct> <fct> <int> <dbl> <int> <dbl>
## 1 Albania Europe 1952 55.2 1282697 1601.
## 2 Albania Europe 1957 59.3 1476505 1942.
## 3 Albania Europe 1962 64.8 1728137 2313.
## 4 Albania Europe 1967 66.2 1984060 2760.
## 5 Albania Europe 1972 67.7 2263554 3313.
## 6 Albania Europe 1977 68.9 2509048 3533.
## 7 Albania Europe 1982 70.4 2780097 3631.
## 8 Albania Europe 1987 72 3075321 3739.
## 9 Albania Europe 1992 71.6 3326498 2497.
## 10 Albania Europe 1997 73.0 3428038 3193.
## # … with 350 more rows
# You can filter on more than one logical condition at a time. This will
# return a tibble with all the gapminder observations from Asia in the year
# 1952. Recall that character strings ("Asia") need quotes, but variable names
# and numbers don't (continent, year, 1952).
gapminder %>%
filter(continent == "Asia", year == 1952)
## # A tibble: 33 × 6
## country continent year lifeExp pop gdpPercap
## <fct> <fct> <int> <dbl> <int> <dbl>
## 1 Afghanistan Asia 1952 28.8 8425333 779.
## 2 Bahrain Asia 1952 50.9 120447 9867.
## 3 Bangladesh Asia 1952 37.5 46886859 684.
## 4 Cambodia Asia 1952 39.4 4693836 368.
## 5 China Asia 1952 44 556263527 400.
## 6 Hong Kong, China Asia 1952 61.0 2125900 3054.
## 7 India Asia 1952 37.4 372000000 547.
## 8 Indonesia Asia 1952 37.5 82052000 750.
## 9 Iran Asia 1952 44.9 17272000 3035.
## 10 Iraq Asia 1952 45.3 5441766 4130.
## # … with 23 more rows
# Read the qelp docs on 'filter()':
?qelp::filter
# 1. Filter gapminder for all the observations from Europe in 2007. ------------
#1@
# __
#@1
# 2. Filter gapminder for all the observations where lifeExp was exactly -------
# equal to 68 years old.
#2@
# __
#@2
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# ----- Logical Operators -----
# The operator '==' reads "is equal to".
# But that's not the only logical operator you can use with 'filter()'.
# '!=': "not equal to"
# '>', '>=', '<', '<=': "greater than", "greater than or equal to", etc.
# '%in%': for "in"
# 3. Filter gapminder for a short list of the richest countries in Asia. -------
#3@
# gapminder %>%
# filter(continent == __, gdpPercap __ 30000)
#@3
# 4. Filter gapminder for observations *IN* the United States, Germany, --------
# and Brazil.
#4@
# gapminder %>%
# filter(country __ c("United States", "Germany", "Brazil"))
#@4
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# ----- select() -----
#
# The function 'select()' lets you select columns (variables) of a tibble
# by name. No quotes are necessary because they're variable names.
gapminder %>%
select(country, continent, year)
## # A tibble: 1,704 × 3
## country continent year
## <fct> <fct> <int>
## 1 Afghanistan Asia 1952
## 2 Afghanistan Asia 1957
## 3 Afghanistan Asia 1962
## 4 Afghanistan Asia 1967
## 5 Afghanistan Asia 1972
## 6 Afghanistan Asia 1977
## 7 Afghanistan Asia 1982
## 8 Afghanistan Asia 1987
## 9 Afghanistan Asia 1992
## 10 Afghanistan Asia 1997
## # … with 1,694 more rows
# 5: Select the last 3 variables of 'gapminder' by name: -----------------------
#5@
# gapminder %>%
# select(__, __, __)
#@5
# You can also use 'select()' to rename variables. For example, to create
# a tibble where the variable 'lifeExp' is changed to the name
# 'life_expectancy', you can do this:
gapminder %>%
select(life_expectancy = lifeExp)
## # A tibble: 1,704 × 1
## life_expectancy
## <dbl>
## 1 28.8
## 2 30.3
## 3 32.0
## 4 34.0
## 5 36.1
## 6 38.4
## 7 39.9
## 8 40.8
## 9 41.7
## 10 41.8
## # … with 1,694 more rows
# Make sure to read the qelp docs on 'select()':
?qelp::select
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# ----- mutate() -----
# Use 'mutate()' to add new variables to your tibble. Those new variables
# can even be transformations of other existing variables. For example,
# we can create a variable called 'total_gdp' that is the product of
# 'pop' and 'gdpPercap'. I've piped it into 'view()' so you can verify that
# it worked.
# gapminder %>%
# mutate(total_gdp = pop*gdpPercap) %>%
# view()
# 6. Use 'mutate()' to create a new variable 'pop_in_thousands'. ---------------
# So if the observation has 'pop' = 97,462, then 'pop_in_thousands' will be
# 97.462.
#6@
# gapminder %>%
# mutate(__)
#@6
# Read the qelp docs on 'mutate()':
?qelp::mutate
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# Great work! You're one step closer to tidyverse enlightenment. Make sure to
# return to this topic to meditate on it later.
# If you're ready, you can move on to the next koan: summarize and group_by.