Extra Practice: Data Wrangling

Click to expand and work on the sections you need.

A good rule of thumb is this: do a bunch of problems in each section until you get bored because everything has gotten too easy.

Pipe Practice |>

From nested functions to pipelines and back again.

Write your code in the editor below each question, then click Run Code. The functions and datasets are already loaded for you.

In case you missed it, there’s a quick 12-second video demonstrating the pipe here.

Question 1: Square root of a mean

Rewrite these nested function calls as a single pipeline using |>.

numbers = c(4, 9, 16)

sqrt(mean(numbers))

Expected output is below, as a hint

[1] 3.109126
Show answer
numbers |>
    mean() |>
    sqrt()

Note that whitespace is flexible - you can break a command into many lines (above) or put it all on one line (below). As long as a line is does not complete a command, R will keep reading, adding the next line to the current command. This is why we can break a pipeline into multiple lines IF we put the pipes at the end of lines, so the commands are left incomplete and R keeps reading.

For very short pipelines, one line will do. In most complex data-wrangling pipelines, where we often have longer lines of code, it is best to add a new line after every pipe operator |> to make the code easier to read.

numbers |> mean() |> sqrt()

Question 2: Round a standard deviation

Rewrite the pipeline as nested function calls (without using |>).

numbers = c(2, 5, 8, 11)

numbers |>
    sd() |>
    round(digits = 2)

Expected output is below, as a hint

[1] 3.87
Show answer
round(sd(numbers), digits = 2)

Remember, the pipe just passes the thing to the left of the |> as the first argument to the function on the right. You can still put in second and third arguments etc as needed. So numbers |> sd() is equivalent to sd(numbers), and sd(numbers) |> round(digits = 2) is equivalent to round(sd(numbers), digits = 2).

Question 3: Endangered Species

Rewrite these nested function calls as a single pipeline using |>.

select(filter(msleep, conservation == "en"), name, sleep_total)

Expected output is below, as a hint (first 4 rows)

# A tibble: 4 × 2
  name            sleep_total
  <chr>                 <dbl>
1 Asian elephant          3.9
2 Golden hamster         14.3
3 Tiger                  15.8
4 Giant armadillo        18.1
Show answer
msleep |>
    filter(conservation == "en") |>
    select(name, sleep_total)

Question 4: Sort the long sleepers

Rewrite this pipeline as nested function calls (without using |>).

msleep |>
    filter(sleep_total > 10) |>
    arrange(desc(sleep_total))

Expected output is below, as a hint (first 4 rows)

# A tibble: 44 × 11
  name                 genus      vore    order           conservation
  <chr>                <chr>      <chr>   <chr>           <chr>       
1 Little brown bat     Myotis     insecti Chiroptera      <NA>        
2 Big brown bat        Eptesicus  insecti Chiroptera      lc          
3 Thick-tailed opposum Lutreolina carni   Didelphimorphia lc          
4 Giant armadillo      Priodontes insecti Cingulata       en          
  sleep_total sleep_rem sleep_cycle awake  brainwt bodywt
        <dbl>     <dbl>       <dbl> <dbl>    <dbl>  <dbl>
1        19.9       2         0.2     4.1  0.00025  0.01 
2        19.7       3.9       0.117   4.3  0.0003   0.023
3        19.4       6.6      NA       4.6 NA        0.37 
4        18.1       6.1      NA       5.9  0.081   60    
# ℹ 40 more rows
Show answer
arrange(filter(msleep, sleep_total > 10), desc(sleep_total))

Question 5: Sleep in minutes

Rewrite these nested function calls as a single pipeline using |>.

select(mutate(msleep, sleep_minutes = sleep_total * 60),
       name, sleep_minutes)

Expected output is below, as a hint (first 4 rows)

# A tibble: 83 × 2
  name                       sleep_minutes
  <chr>                              <dbl>
1 Cheetah                              726
2 Owl monkey                          1020
3 Mountain beaver                      864
4 Greater short-tailed shrew           894
# ℹ 79 more rows
Show answer
msleep |>
    mutate(sleep_minutes = sleep_total * 60) |>
    select(name, sleep_minutes)

Question 6: Average sleep by diet

Rewrite this pipeline as nested function calls (without using |>).

msleep |>
    group_by(vore) |>
    summarize(mean_sleep = mean(sleep_total))

Expected output is below, as a hint (first 4 rows)

# A tibble: 5 × 2
  vore    mean_sleep
  <chr>        <dbl>
1 carni        10.4 
2 herbi         9.51
3 insecti      14.9 
4 omni         10.9 
# ℹ 1 more row
Show answer
summarize(group_by(msleep, vore),
          mean_sleep = mean(sleep_total))

Question 7: Average sleep of herbivores

Rewrite these nested function calls as a single pipeline using |>.

summarize(mutate(filter(msleep, vore == "herbi"),
                 sleep_minutes = sleep_total * 60),
          mean_minutes = mean(sleep_minutes))

Expected output is below, as a hint (first 1 row)

# A tibble: 1 × 1
  mean_minutes
         <dbl>
1         571.
Show answer
msleep |>
    filter(vore == "herbi") |>
    mutate(sleep_minutes = sleep_total * 60) |>
    summarize(mean_minutes = mean(sleep_minutes))

Question 8: Count animals by diet

Rewrite this pipeline as nested function calls (without using |>).

msleep |>
    group_by(vore) |>
    summarize(n = n()) |>
    arrange(desc(n))

Expected output is below, as a hint (first 4 rows)

# A tibble: 5 × 2
  vore      n
  <chr> <int>
1 herbi    32
2 omni     20
3 carni    19
4 <NA>      7
# ℹ 1 more row
Show answer
arrange(summarize(group_by(msleep, vore), n = n()),
        desc(n))

Question 9: Compare sleep variability

Rewrite these nested function calls as a single pipeline using |>.

arrange(summarize(group_by(filter(msleep, vore != "insecti"),
                           vore),
                  sd_sleep = sd(sleep_total)),
        desc(sd_sleep))

Expected output is below, as a hint (first 3 rows)

# A tibble: 3 × 2
  vore  sd_sleep
  <chr>    <dbl>
1 herbi     4.88
2 carni     4.67
3 omni      2.95
Show answer
msleep |>
    filter(vore != "insecti") |>
    group_by(vore) |>
    summarize(sd_sleep = sd(sleep_total)) |>
    arrange(desc(sd_sleep))

Question 10: Rank average body weights by diet

Rewrite this pipeline as nested function calls (without using |>).

msleep |>
    filter(sleep_total < 10) |>
    mutate(bodywt_g = bodywt * 1000) |>
    group_by(vore) |>
    summarize(mean_bodywt_g = mean(bodywt_g)) |>
    arrange(desc(mean_bodywt_g))

Expected output is below, as a hint (first 4 rows)

# A tibble: 5 × 2
  vore    mean_bodywt_g
  <chr>           <dbl>
1 herbi         733186.
2 carni         153029.
3 omni           22778.
4 insecti         2288.
# ℹ 1 more row
Show answer
arrange(summarize(group_by(mutate(filter(msleep, sleep_total < 10),
                                 bodywt_g = bodywt * 1000),
                          vore),
                  mean_bodywt_g = mean(bodywt_g)),
        desc(mean_bodywt_g))
Know when to use filter, select, mutate, summarize, arrange, and group_by

Fill in each blank with one function name: filter, select, mutate, summarize, arrange, or group_by. Replace the blank in each editor, then click Run Code. Each preview shows the first four rows and the columns relevant to the question; run the pipeline on the full msleep dataset.

Question 1: Weight in grams

Task: Add a bodywt_g column containing body weight in grams. The bodywt column is in kilograms. Keep all existing rows and columns.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name bodywt
Cheetah 50.000
Owl monkey 0.480
Mountain beaver 1.350
Greater short-tailed shrew 0.019

Expected output is below, as a hint (first 4 rows)

# A tibble: 83 × 12
  name                       genus      vore  order        conservation
  <chr>                      <chr>      <chr> <chr>        <chr>       
1 Cheetah                    Acinonyx   carni Carnivora    lc          
2 Owl monkey                 Aotus      omni  Primates     <NA>        
3 Mountain beaver            Aplodontia herbi Rodentia     nt          
4 Greater short-tailed shrew Blarina    omni  Soricomorpha lc          
  sleep_total sleep_rem sleep_cycle awake  brainwt bodywt bodywt_g
        <dbl>     <dbl>       <dbl> <dbl>    <dbl>  <dbl>    <dbl>
1        12.1      NA        NA      11.9 NA       50        50000
2        17         1.8      NA       7    0.0155   0.48       480
3        14.4       2.4      NA       9.6 NA        1.35      1350
4        14.9       2.3       0.133   9.1  0.00029  0.019       19
# ℹ 79 more rows
Show answer

Answer: mutate

msleep |>
    mutate(bodywt_g = bodywt * 1000)

Question 2: One overall average

Task: Return one row containing the mean daily sleep across all animals.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name sleep_total
Cheetah 12.1
Owl monkey 17.0
Mountain beaver 14.4
Greater short-tailed shrew 14.9

Expected output is below, as a hint (first 1 row)

# A tibble: 1 × 1
  mean_sleep
       <dbl>
1       10.4
Show answer

Answer: summarize

msleep |>
    summarize(mean_sleep = mean(sleep_total))

Question 3: Small, long-sleeping animals

Task: Keep only animals that weigh less than 1 kilogram and sleep more than 12 hours per day.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name bodywt sleep_total
Cheetah 50.000 12.1
Owl monkey 0.480 17.0
Mountain beaver 1.350 14.4
Greater short-tailed shrew 0.019 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 20 × 11
  name                       genus      vore    order        conservation
  <chr>                      <chr>      <chr>   <chr>        <chr>       
1 Owl monkey                 Aotus      omni    Primates     <NA>        
2 Greater short-tailed shrew Blarina    omni    Soricomorpha lc          
3 Chinchilla                 Chinchilla herbi   Rodentia     domesticated
4 Big brown bat              Eptesicus  insecti Chiroptera   lc          
  sleep_total sleep_rem sleep_cycle awake brainwt bodywt
        <dbl>     <dbl>       <dbl> <dbl>   <dbl>  <dbl>
1        17         1.8      NA       7   0.0155   0.48 
2        14.9       2.3       0.133   9.1 0.00029  0.019
3        12.5       1.5       0.117  11.5 0.0064   0.42 
4        19.7       3.9       0.117   4.3 0.0003   0.023
# ℹ 16 more rows
Show answer

Answer: filter

msleep |>
    filter(bodywt < 1 & sleep_total > 12)

filter is for rows, select is for columns

Question 4: Two diet categories

Task: Keep only animals whose diet is “carni” or “omni”.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name vore
Cheetah carni
Owl monkey omni
Mountain beaver herbi
Greater short-tailed shrew omni

Expected output is below, as a hint (first 4 rows)

# A tibble: 39 × 11
  name                       genus       vore  order        conservation
  <chr>                      <chr>       <chr> <chr>        <chr>       
1 Cheetah                    Acinonyx    carni Carnivora    lc          
2 Owl monkey                 Aotus       omni  Primates     <NA>        
3 Greater short-tailed shrew Blarina     omni  Soricomorpha lc          
4 Northern fur seal          Callorhinus carni Carnivora    vu          
  sleep_total sleep_rem sleep_cycle awake  brainwt bodywt
        <dbl>     <dbl>       <dbl> <dbl>    <dbl>  <dbl>
1        12.1      NA        NA      11.9 NA       50    
2        17         1.8      NA       7    0.0155   0.48 
3        14.9       2.3       0.133   9.1  0.00029  0.019
4         8.7       1.4       0.383  15.3 NA       20.5  
# ℹ 35 more rows
Show answer

Answer: filter

msleep |>
    filter(vore %in% c("carni", "omni"))

filter is for rows, select is for columns

Question 5: Drop conservation status

Task: Remove the conservation column while keeping all other columns.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name vore conservation
Cheetah carni lc
Owl monkey omni NA
Mountain beaver herbi nt
Greater short-tailed shrew omni lc

Expected output is below, as a hint (first 4 rows)

# A tibble: 83 × 10
  name                       genus      vore  order        sleep_total sleep_rem
  <chr>                      <chr>      <chr> <chr>              <dbl>     <dbl>
1 Cheetah                    Acinonyx   carni Carnivora           12.1      NA  
2 Owl monkey                 Aotus      omni  Primates            17         1.8
3 Mountain beaver            Aplodontia herbi Rodentia            14.4       2.4
4 Greater short-tailed shrew Blarina    omni  Soricomorpha        14.9       2.3
  sleep_cycle awake  brainwt bodywt
        <dbl> <dbl>    <dbl>  <dbl>
1      NA      11.9 NA       50    
2      NA       7    0.0155   0.48 
3      NA       9.6 NA        1.35 
4       0.133   9.1  0.00029  0.019
# ℹ 79 more rows
Show answer

Answer: select

msleep |>
    select(-conservation)

filter is for rows, select is for columns

Question 6: Heaviest first

Task: Put the animals in order from greatest to least body weight.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name bodywt
Cheetah 50.000
Owl monkey 0.480
Mountain beaver 1.350
Greater short-tailed shrew 0.019

Expected output is below, as a hint (first 4 rows)

# A tibble: 83 × 11
  name             genus         vore  order        conservation sleep_total
  <chr>            <chr>         <chr> <chr>        <chr>              <dbl>
1 African elephant Loxodonta     herbi Proboscidea  vu                   3.3
2 Asian elephant   Elephas       herbi Proboscidea  en                   3.9
3 Giraffe          Giraffa       herbi Artiodactyla cd                   1.9
4 Pilot whale      Globicephalus carni Cetacea      cd                   2.7
  sleep_rem sleep_cycle awake brainwt bodywt
      <dbl>       <dbl> <dbl>   <dbl>  <dbl>
1      NA            NA  20.7    5.71  6654 
2      NA            NA  20.1    4.60  2547 
3       0.4          NA  22.1   NA      900.
4       0.1          NA  21.4   NA      800 
# ℹ 79 more rows
Show answer

Answer: arrange

msleep |>
    arrange(desc(bodywt))

Question 7: Names and diets

Task: Keep only the name and diet columns, in that order.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name vore sleep_total
Cheetah carni 12.1
Owl monkey omni 17.0
Mountain beaver herbi 14.4
Greater short-tailed shrew omni 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 83 × 2
  name                       vore 
  <chr>                      <chr>
1 Cheetah                    carni
2 Owl monkey                 omni 
3 Mountain beaver            herbi
4 Greater short-tailed shrew omni 
# ℹ 79 more rows
Show answer

Answer: select

msleep |>
    select(name, vore)

filter is for rows, select is for columns

Question 8: Count each animal order

Task: Count the animals separately for each taxonomic order.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name order
Cheetah Carnivora
Owl monkey Primates
Mountain beaver Rodentia
Greater short-tailed shrew Soricomorpha

Expected output is below, as a hint (first 4 rows)

# A tibble: 19 × 2
  order        n_animals
  <chr>            <int>
1 Afrosoricida         1
2 Artiodactyla         6
3 Carnivora           12
4 Cetacea              3
# ℹ 15 more rows
Show answer

Answer: group_by

msleep |>
    group_by(order) |>
    summarize(n_animals = n())

Question 9: Only herbivores

Task: Keep only the herbivores, whose diet is recorded as “herbi”.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name vore
Cheetah carni
Owl monkey omni
Mountain beaver herbi
Greater short-tailed shrew omni

Expected output is below, as a hint (first 4 rows)

# A tibble: 32 × 11
  name             genus      vore  order        conservation sleep_total
  <chr>            <chr>      <chr> <chr>        <chr>              <dbl>
1 Mountain beaver  Aplodontia herbi Rodentia     nt                  14.4
2 Cow              Bos        herbi Artiodactyla domesticated         4  
3 Three-toed sloth Bradypus   herbi Pilosa       <NA>                14.4
4 Roe deer         Capreolus  herbi Artiodactyla lc                   3  
  sleep_rem sleep_cycle awake brainwt bodywt
      <dbl>       <dbl> <dbl>   <dbl>  <dbl>
1       2.4      NA       9.6 NA        1.35
2       0.7       0.667  20    0.423  600   
3       2.2       0.767   9.6 NA        3.85
4      NA        NA      21    0.0982  14.8 
# ℹ 28 more rows
Show answer

Answer: filter

msleep |>
    filter(vore == "herbi")

filter is for rows, select is for columns

Question 10: Fraction of the day asleep

Task: Add a column containing the fraction of a 24-hour day each animal spends asleep. Keep all existing rows and columns.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name sleep_total
Cheetah 12.1
Owl monkey 17.0
Mountain beaver 14.4
Greater short-tailed shrew 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 83 × 12
  name                       genus      vore  order        conservation
  <chr>                      <chr>      <chr> <chr>        <chr>       
1 Cheetah                    Acinonyx   carni Carnivora    lc          
2 Owl monkey                 Aotus      omni  Primates     <NA>        
3 Mountain beaver            Aplodontia herbi Rodentia     nt          
4 Greater short-tailed shrew Blarina    omni  Soricomorpha lc          
  sleep_total sleep_rem sleep_cycle awake  brainwt bodywt sleep_fraction
        <dbl>     <dbl>       <dbl> <dbl>    <dbl>  <dbl>          <dbl>
1        12.1      NA        NA      11.9 NA       50              0.504
2        17         1.8      NA       7    0.0155   0.48           0.708
3        14.4       2.4      NA       9.6 NA        1.35           0.6  
4        14.9       2.3       0.133   9.1  0.00029  0.019          0.621
# ℹ 79 more rows
Show answer

Answer: mutate

msleep |>
    mutate(sleep_fraction = sleep_total / 24)

Question 11: Alphabetical carnivores

Task: Keep the carnivores (“carni”), then put their names in alphabetical order.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name vore
Cheetah carni
Owl monkey omni
Mountain beaver herbi
Greater short-tailed shrew omni

Expected output is below, as a hint (first 4 rows)

# A tibble: 19 × 11
  name                 genus    vore  order     conservation sleep_total
  <chr>                <chr>    <chr> <chr>     <chr>              <dbl>
1 Arctic fox           Vulpes   carni Carnivora <NA>                12.5
2 Bottle-nosed dolphin Tursiops carni Cetacea   <NA>                 5.2
3 Caspian seal         Phoca    carni Carnivora vu                   3.5
4 Cheetah              Acinonyx carni Carnivora lc                  12.1
  sleep_rem sleep_cycle awake brainwt bodywt
      <dbl>       <dbl> <dbl>   <dbl>  <dbl>
1      NA            NA  11.5  0.0445   3.38
2      NA            NA  18.8 NA      173.  
3       0.4          NA  20.5 NA       86   
4      NA            NA  11.9 NA       50   
# ℹ 15 more rows
Show answer

Answer: arrange

msleep |>
    filter(vore == "carni") |>
    arrange(name)

Question 12: Convert the existing sleep column

Task: Replace the values in sleep_total with minutes instead of hours, keeping all rows and other columns.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name sleep_total
Cheetah 12.1
Owl monkey 17.0
Mountain beaver 14.4
Greater short-tailed shrew 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 83 × 11
  name                       genus      vore  order        conservation
  <chr>                      <chr>      <chr> <chr>        <chr>       
1 Cheetah                    Acinonyx   carni Carnivora    lc          
2 Owl monkey                 Aotus      omni  Primates     <NA>        
3 Mountain beaver            Aplodontia herbi Rodentia     nt          
4 Greater short-tailed shrew Blarina    omni  Soricomorpha lc          
  sleep_total sleep_rem sleep_cycle awake  brainwt bodywt
        <dbl>     <dbl>       <dbl> <dbl>    <dbl>  <dbl>
1         726      NA        NA      11.9 NA       50    
2        1020       1.8      NA       7    0.0155   0.48 
3         864       2.4      NA       9.6 NA        1.35 
4         894       2.3       0.133   9.1  0.00029  0.019
# ℹ 79 more rows
Show answer

Answer: mutate

msleep |>
    mutate(sleep_total = sleep_total * 60)

Question 13: Count each diet

Task: Return one row per diet category, with the number of animals in that category.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name vore
Cheetah carni
Owl monkey omni
Mountain beaver herbi
Greater short-tailed shrew omni

Expected output is below, as a hint (first 4 rows)

# A tibble: 5 × 2
  vore    n_animals
  <chr>       <int>
1 carni          19
2 herbi          32
3 insecti         5
4 omni           20
# ℹ 1 more row
Show answer

Answer: summarize

msleep |>
    group_by(vore) |>
    summarize(n_animals = n())

Question 14: Shortest sleepers first

Task: Put the animals in order from least to most daily sleep.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name sleep_total
Cheetah 12.1
Owl monkey 17.0
Mountain beaver 14.4
Greater short-tailed shrew 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 83 × 11
  name        genus         vore  order          conservation sleep_total
  <chr>       <chr>         <chr> <chr>          <chr>              <dbl>
1 Giraffe     Giraffa       herbi Artiodactyla   cd                   1.9
2 Pilot whale Globicephalus carni Cetacea        cd                   2.7
3 Horse       Equus         herbi Perissodactyla domesticated         2.9
4 Roe deer    Capreolus     herbi Artiodactyla   lc                   3  
  sleep_rem sleep_cycle awake brainwt bodywt
      <dbl>       <dbl> <dbl>   <dbl>  <dbl>
1       0.4          NA  22.1 NA       900. 
2       0.1          NA  21.4 NA       800  
3       0.6           1  21.1  0.655   521  
4      NA            NA  21    0.0982   14.8
# ℹ 79 more rows
Show answer

Answer: arrange

msleep |>
    arrange(sleep_total)

Question 15: Sleep by conservation status

Task: Calculate a separate mean daily sleep for each conservation status.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name conservation sleep_total
Cheetah lc 12.1
Owl monkey NA 17.0
Mountain beaver nt 14.4
Greater short-tailed shrew lc 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 7 × 2
  conservation mean_sleep
  <chr>             <dbl>
1 cd                 2.3 
2 domesticated       7.58
3 en                13.0 
4 lc                11.4 
# ℹ 3 more rows
Show answer

Answer: group_by

msleep |>
    group_by(conservation) |>
    summarize(mean_sleep = mean(sleep_total))

Question 16: The longest sleep duration

Task: Return one row containing the largest daily sleep duration in the dataset.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name sleep_total
Cheetah 12.1
Owl monkey 17.0
Mountain beaver 14.4
Greater short-tailed shrew 14.9

Expected output is below, as a hint (first 1 row)

# A tibble: 1 × 1
  max_sleep
      <dbl>
1      19.9
Show answer

Answer: summarize

msleep |>
    summarize(max_sleep = max(sleep_total))

Question 17: Long sleepers

Task: Keep only animals that sleep more than 10 hours per day.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name sleep_total
Cheetah 12.1
Owl monkey 17.0
Mountain beaver 14.4
Greater short-tailed shrew 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 44 × 11
  name                       genus      vore  order        conservation
  <chr>                      <chr>      <chr> <chr>        <chr>       
1 Cheetah                    Acinonyx   carni Carnivora    lc          
2 Owl monkey                 Aotus      omni  Primates     <NA>        
3 Mountain beaver            Aplodontia herbi Rodentia     nt          
4 Greater short-tailed shrew Blarina    omni  Soricomorpha lc          
  sleep_total sleep_rem sleep_cycle awake  brainwt bodywt
        <dbl>     <dbl>       <dbl> <dbl>    <dbl>  <dbl>
1        12.1      NA        NA      11.9 NA       50    
2        17         1.8      NA       7    0.0155   0.48 
3        14.4       2.4      NA       9.6 NA        1.35 
4        14.9       2.3       0.133   9.1  0.00029  0.019
# ℹ 40 more rows
Show answer

Answer: filter

msleep |>
    filter(sleep_total > 10)

filter is for rows, select is for columns

Question 18: Average sleep for each diet

Task: Calculate a separate mean daily sleep for each diet category.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name vore sleep_total
Cheetah carni 12.1
Owl monkey omni 17.0
Mountain beaver herbi 14.4
Greater short-tailed shrew omni 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 5 × 2
  vore    mean_sleep
  <chr>        <dbl>
1 carni        10.4 
2 herbi         9.51
3 insecti      14.9 
4 omni         10.9 
# ℹ 1 more row
Show answer

Answer: group_by

msleep |>
    group_by(vore) |>
    summarize(mean_sleep = mean(sleep_total))

Question 19: Keep two columns after filtering

Task: Among animals sleeping more than 10 hours per day, keep only name and sleep_total.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name vore sleep_total
Cheetah carni 12.1
Owl monkey omni 17.0
Mountain beaver herbi 14.4
Greater short-tailed shrew omni 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 44 × 2
  name                       sleep_total
  <chr>                            <dbl>
1 Cheetah                           12.1
2 Owl monkey                        17  
3 Mountain beaver                   14.4
4 Greater short-tailed shrew        14.9
# ℹ 40 more rows
Show answer

Answer: select

msleep |>
    filter(sleep_total > 10) |>
    select(name, sleep_total)

filter is for rows, select is for columns

Question 20: Sleep in minutes

Task: Add a column giving daily sleep in minutes. Keep all existing rows and columns.

Replace the blank with one of: filter, select, mutate, summarize, arrange, or group_by.

Preview of relevant columns of msleep:

name sleep_total
Cheetah 12.1
Owl monkey 17.0
Mountain beaver 14.4
Greater short-tailed shrew 14.9

Expected output is below, as a hint (first 4 rows)

# A tibble: 83 × 12
  name                       genus      vore  order        conservation
  <chr>                      <chr>      <chr> <chr>        <chr>       
1 Cheetah                    Acinonyx   carni Carnivora    lc          
2 Owl monkey                 Aotus      omni  Primates     <NA>        
3 Mountain beaver            Aplodontia herbi Rodentia     nt          
4 Greater short-tailed shrew Blarina    omni  Soricomorpha lc          
  sleep_total sleep_rem sleep_cycle awake  brainwt bodywt sleep_minutes
        <dbl>     <dbl>       <dbl> <dbl>    <dbl>  <dbl>         <dbl>
1        12.1      NA        NA      11.9 NA       50               726
2        17         1.8      NA       7    0.0155   0.48           1020
3        14.4       2.4      NA       9.6 NA        1.35            864
4        14.9       2.3       0.133   9.1  0.00029  0.019           894
# ℹ 79 more rows
Show answer

Answer: mutate

msleep |>
    mutate(sleep_minutes = sleep_total * 60)
Practice with conditions for filtering == != > >= < <= %in% & |

Use diamonds, a dataset of 53,940 diamonds included in ggplot2. Each row is one diamond. price is in US dollars, carat measures weight, and x y and z measure the length width and height of the diamond, in millimeters. cut, color, and clarity are other meaningful attributes that diamond-appraisers consider.

For each question, you’ll replace the blank inside filter() with one or more conditions, then click Run Code. Keep all columns. The dataset is already loaded.

Preview of diamonds (first 4 rows, all 10 columns):

carat cut color clarity depth table price x y z
0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63

Question 1: A price ceiling

Task: Keep diamonds that cost at most $800.

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 9,804 × 10
  carat cut     color clarity depth table price     x     y     z
  <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43
2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31
3  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31
4  0.29 Premium I     VS2      62.4    58   334  4.2   4.23  2.63
# ℹ 9,800 more rows
Show answer
diamonds |>
    filter(price <= 800)

Question 2: Skip one cut

Task: Keep diamonds whose cut is not “Premium”.

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 40,149 × 10
  carat cut       color clarity depth table price     x     y     z
  <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.23 Ideal     E     SI2      61.5    55   326  3.95  3.98  2.43
2  0.23 Good      E     VS1      56.9    65   327  4.05  4.07  2.31
3  0.31 Good      J     SI2      63.3    58   335  4.34  4.35  2.75
4  0.24 Very Good J     VVS2     62.8    57   336  3.94  3.96  2.48
# ℹ 40,145 more rows
Show answer
diamonds |>
    filter(cut != "Premium")

Question 3: More than one carat

Task: Keep diamonds weighing more than 1 carat.

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 17,502 × 10
  carat cut       color clarity depth table price     x     y     z
  <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  1.17 Very Good J     I1       60.2    61  2774  6.83  6.9   4.13
2  1.01 Premium   F     I1       61.8    60  2781  6.39  6.36  3.94
3  1.01 Fair      E     I1       64.5    58  2788  6.29  6.21  4.03
4  1.01 Premium   H     SI2      62.7    59  2788  6.31  6.22  3.93
# ℹ 17,498 more rows
Show answer
diamonds |>
    filter(carat > 1)

Question 4: One clarity grade

Task: Keep diamonds whose clarity is “VS2”.

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 12,258 × 10
  carat cut       color clarity depth table price     x     y     z
  <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.29 Premium   I     VS2      62.4    58   334  4.2   4.23  2.63
2  0.22 Fair      E     VS2      65.1    61   337  3.87  3.78  2.49
3  0.23 Very Good E     VS2      63.8    55   352  3.85  3.92  2.48
4  0.3  Very Good J     VS2      62.2    57   357  4.28  4.3   2.67
# ℹ 12,254 more rows
Show answer
diamonds |>
    filter(clarity == "VS2")

Question 5: At least five millimeters

Task: Keep diamonds whose length (x)is at least 5 mm.

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 36,354 × 10
  carat cut       color clarity depth table price     x     y     z
  <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.7  Ideal     E     SI1      62.5    57  2757  5.7   5.72  3.57
2  0.86 Fair      E     SI2      55.1    69  2757  6.45  6.33  3.52
3  0.7  Ideal     G     VS2      61.6    56  2757  5.7   5.67  3.5 
4  0.71 Very Good E     VS2      62.4    57  2759  5.68  5.73  3.56
# ℹ 36,350 more rows
Show answer
diamonds |>
    filter(x >= 5)

Question 6: Below half a carat

Task: Keep diamonds weighing less than 0.5 carats.

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 17,674 × 10
  carat cut     color clarity depth table price     x     y     z
  <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43
2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31
3  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31
4  0.29 Premium I     VS2      62.4    58   334  4.2   4.23  2.63
# ℹ 17,670 more rows
Show answer
diamonds |>
    filter(carat < 0.5)

Question 7: Large or inexpensive

Task: Keep diamonds that weigh at least 2 carats or cost less than $500 (or both).

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 3,883 × 10
  carat cut     color clarity depth table price     x     y     z
  <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43
2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31
3  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31
4  0.29 Premium I     VS2      62.4    58   334  4.2   4.23  2.63
# ℹ 3,879 more rows
Show answer
diamonds |>
    filter(carat >= 2 | price < 500)

Question 8: Two cuts within budget

Task: Keep diamonds whose cut is either “Ideal” or “Premium” and whose price is at most $1,500. Use %in% to specify the two cuts.

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 14,010 × 10
  carat cut     color clarity depth table price     x     y     z
  <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43
2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31
3  0.29 Premium I     VS2      62.4    58   334  4.2   4.23  2.63
4  0.23 Ideal   J     VS1      62.8    56   340  3.93  3.9   2.46
# ℹ 14,006 more rows
Show answer
diamonds |>
    filter(cut %in% c("Ideal", "Premium") & price <= 1500)

Question 9: Either cut, with a price limit

Task: Keep diamonds whose cut is “Fair” or “Good”, with a price below $1,000 in either case. Use both | and & in your condition.

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 1,221 × 10
  carat cut   color clarity depth table price     x     y     z
  <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.23 Good  E     VS1      56.9    65   327  4.05  4.07  2.31
2  0.31 Good  J     SI2      63.3    58   335  4.34  4.35  2.75
3  0.22 Fair  E     VS2      65.1    61   337  3.87  3.78  2.49
4  0.3  Good  J     SI1      64      55   339  4.25  4.28  2.73
# ℹ 1,217 more rows
Show answer
diamonds |>
    filter((cut == "Fair" | cut == "Good") & price < 1000)

Question 10: Exclude three colors

Task: Keep diamonds weighing more than 1 carat whose color is not “D”, “E”, or “F”. Use ! and %in% to exclude those colors. This one is tricky, you may have to tinker with the syntaxa bit to find what works.

Replace the blank inside filter() with the condition(s) that select these diamonds.

Expected output is below, as a hint (first 4 rows)

# A tibble: 11,688 × 10
  carat cut       color clarity depth table price     x     y     z
  <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  1.17 Very Good J     I1       60.2    61  2774  6.83  6.9   4.13
2  1.01 Premium   H     SI2      62.7    59  2788  6.31  6.22  3.93
3  1.05 Very Good J     SI2      63.2    56  2789  6.49  6.45  4.09
4  1.05 Fair      J     SI2      65.8    59  2789  6.41  6.27  4.18
# ℹ 11,684 more rows
Show answer
diamonds |>
    filter(carat > 1 & !(color %in% c("D", "E", "F")))
Real tasks: I give you a problem, you build the pipeline


Each problem below should be answered with one single pipeline. Each problem uses a different dataset that is already loaded for you (they are all from tidyverse).

Question 1: mpg - car fuel efficiency data

The mpg dataset records fuel economy for different car models and configurations. cty and hwy are city and highway fuel economy in miles per gallon; higher values mean greater fuel efficiency. cyl is the number of “cylinders” (pistons) in the engine, and class is a broad category of vehicle type.

Preview of relevant columns of mpg (first 4 rows):

manufacturer model year cyl cty hwy class
audi a4 1999 4 18 29 compact
audi a4 1999 4 21 29 compact
audi a4 2008 4 20 31 compact
audi a4 2008 4 21 30 compact

Task: In one pipeline, make a shortlist of fuel-efficient cars. Keep cars with highway fuel economy of at least 30 miles per gallon, and return only manufacturer, model, cty, and hwy columns, in that order. Sort them from most to least fuel efficient in highway driving.

Expected output is below, as a hint (first 4 rows)

# A tibble: 26 × 4
  manufacturer model        cty   hwy
  <chr>        <chr>      <int> <int>
1 volkswagen   jetta         33    44
2 volkswagen   new beetle    35    44
3 volkswagen   new beetle    29    41
4 toyota       corolla       28    37
# ℹ 22 more rows
Show answer
mpg |>
    filter(hwy >= 30) |>
    select(manufacturer, model, cty, hwy) |>
    arrange(desc(hwy))

Note: A model can appear more than once because the data include different configurations of the same car.

Question 2: starwars - Star Wars characters

The starwars dataset has one row per character in the Star Wars film series. The characters in these films include humans among many other types of beings. species identifies the character’s species, height is in centimeters, mass is in kilograms. Some values may be missing (NA).

Here are a few rows of starwars:

name species height mass
Chewbacca Wookiee 228 112
Roos Tarpals Gungan 224 82
Poe Dameron Human NA NA
BB8 Droid NA NA
Bib Fortuna Twi’lek 180 NA
R5-D4 Droid 97 32
Tarfful Wookiee 234 136
Ayla Secura Twi’lek 178 55
Jar Jar Binks Gungan 196 66
Jango Fett Human 183 79

Task: How do the heights and weights of Humans, Droids, and Wookiees compare? These are three of the species types in the Star Wars universe. We aren’t concerned with any other species. Write a single pipeline that produces a table with the average height, average mass, and total number of characters in each of these three species. Hint: use na.rm = TRUE when computing means.

Expected output is below, as a hint (first 3 rows)

# A tibble: 3 × 4
  species mean_height_cm mean_mass_kg n_characters
  <chr>            <dbl>        <dbl>        <int>
1 Droid             131.         69.8            6
2 Human             178          81.3           35
3 Wookiee           231         124              2
Show answer
starwars |>
    filter(species %in% c("Human", "Droid", "Wookiee")) |>
    group_by(species) |>
    summarize(mean_height_cm = mean(height, na.rm = TRUE),
              mean_mass_kg = mean(mass, na.rm = TRUE),
              n_characters = n())

Note: n_characters includes characters with missing height or weight data, while the means of height and weight use only characters with known measurements.

Question 3: economics - US economic measurements

The economics dataset contains yearly US economic measurements. Each row is one complete calendar year. year is an ordinary number, and unemploy is the average monthly number of unemployed people during that year, in thousands. This prepared dataset is already loaded.

Preview of relevant columns of economics (first 4 rows):

year unemploy
1968 2797.417
1969 2830.167
1970 4127.333
1971 5021.667

Task: Make line plot of the number of unemployed people in millions over time, starting in the year 2000. Give the axes readable labels.

Expected output is below, as a hint

Line plot of the average monthly number of unemployed people in millions by year from 2000 onward, peaking around 2009–2010.

Show answer
economics |>
    filter(year >= 2000) |>
    mutate(unemployed_millions = unemploy / 1000) |>
    ggplot(aes(x = year, y = unemployed_millions)) +
    geom_line() +
    labs(x = "Year", y = "Average unemployed people (millions)")

Question 4: midwest - US county demographics in the Midwest states

The midwest dataset has one row per county (a county is a subdivision of a state). state is the state abbreviation (e.g., “OH” for Ohio), inmetro is 1 for metropolitan counties and 0 otherwise, poptotal is the population, and percbelowpoverty is the percentage of people below the poverty line.

Preview of relevant columns of midwest (first 4 rows):

county state inmetro poptotal percbelowpoverty
ADAMS IL 0 66090 13.151443
ALEXANDER IL 0 10626 32.244278
BOND IL 0 14991 12.068844
BOONE IL 1 30806 7.209019

Task: Calculate the total number of counties, total population, and average county poverty rate for only metropolitan counties each state. This last quantity should give every county equal weight, which is not exactly correct approach but fine for this exercise.

Expected output is below, as a hint (first 4 rows)

# A tibble: 5 × 4
  state n_counties total_pop_millions mean_county_poverty_pct
  <chr>      <int>              <dbl>                   <dbl>
1 IL            28               9.57                    9.56
2 IN            37               3.96                    9.59
3 MI            25               7.70                   11.3 
4 OH            40               8.91                   11.5 
# ℹ 1 more row
Show answer
midwest |>
    filter(inmetro == 1) |>
    mutate(pop_millions = poptotal / 1000000) |>
    group_by(state) |>
    summarize(n_counties = n(),
              total_pop_millions = sum(pop_millions),
              mean_county_poverty_pct = mean(percbelowpoverty))

Question 5: txhousing - Texas housing data

For this exercise, txhousing contains data on median home price sales in cities in Texas over various years. median_price is the median home sale price in dollars that year.

Preview of relevant columns of txhousing (first 4 rows):

city year median_price
Abilene 2000 71400
Abilene 2001 64500
Abilene 2002 64000
Abilene 2003 70000

Task: How do home prices in “Austin”, “Dallas”, and “Houston” compare over time? Make a plot of the median sale prices in thousands of dollars for these three cities over the years. Use a separate colored line for each city. Create readable axis labels and add a sensible title.

Expected output is below, as a hint

Line plot comparing median sale prices by year in thousands of dollars for Austin, Dallas, and Houston.

Show answer
txhousing |>
    filter(city %in% c("Austin", "Dallas", "Houston")) |>
    mutate(median_thousands = median_price / 1000) |>
    ggplot(aes(x = year, y = median_thousands, color = city)) +
    geom_line() +
    labs(x = "Year", y = "Median sale price (thousands of dollars)",
         color = "City",
         title = "Texas median home prices over time")

You can also do quick calculations directly in ggplot to save yourself a step:

txhousing |>
    filter(city %in% c("Austin", "Dallas", "Houston")) |>
    ggplot(aes(x = year, y = median_price / 1000, color = city)) +
    geom_line() +
    labs(x = "Year", y = "Median sale price (thousands of dollars)",
         color = "City",
         title = "Texas median home prices over time")