library(tidyverse)
PA 8: The 12 Days of Christmas
Introduction
The song “12 Days of Christmas”, written around 1780, tells the tale of many gifts a person receives in the days leading up to Christmas.
These gifts repeat and compound; on the first day, the narrator receives
A partridge in a pear tree.
On the twelfth day, they receive
Twelve Drummers Drumming
Eleven Pipers Piping
Ten Lords a Leaping
Nine Ladies Waiting
Eight Maids a Milking
Seven Swans a Swimming
Six Geese a Laying
Five Golden Rings
Four Calling Birds
Three French Hens
Two Turtle Doves
And a Partridge in a Pear Tree
This week, your task will be to write functions that automatically sing this very repetitive song. In the practice activity, we will start by writing two helper functions which we will use later to write a function which sings the entire song.
This task is complex. It requires many different types of abilities. Everyone will be good at some of these abilities but nobody will be good at all of them. In order to produce the best product possible, you will need to use the skills of each member of your group.
Data set
Run the code provided to load in a data set called xmas
that contains the crucial information about the gifts in the song. We will use this data set to test out our functions as we work on them.
<- read.csv("https://github.com/earobinson95/stat331-calpoly/raw/master/practice-activities/data/xmas.csv") |>
xmas ::clean_names() janitor
While we’re at it, let’s make a smaller version of the xmas
data set. This way we can try out our functions on the small version first before we test them on the full data set.
<- slice_sample(xmas, n = 2) xmas_small
Advice
Your functions can - and should! - reference each other. That is, don’t duplicate code; use earlier, smaller functions inside your larger functions.
Don’t sweat the small stuff, this activity focuses on learning about vectorized and non-vectorized functions not on getting the output to look as nice as possible.
Step 1 – Pluralizing the Gifts
The gifts in the xmas
dataset are listed in singular. For example, on day five the narrator receives “five golden rings”, but the entry in the xmas
data set for the gift
on day five simply says "ring"
.
Using the skeleton of the pluralize_gift()
function, fill in the ____
so that the function takes a gift and returns the appropriate plural.
Here are some tips for completing this task:
The gifts on days six (goose) and nine (lady) have unusual pluralization. You may assume that in other data sets, there will be no additional special cases besides these types.
Your should absolutely not “hard-code” anything into this function. For example, the word “goose” should not appear anywhere in the function.
# Function that takes a noun and makes it plural
# Arguments -- gift -- A string or vector of strings
# Return -- A string or vector of strings with the pluralized words
<- function(gift){
pluralize_gift
# Check if the word ends in a y
if(____){
# Replace the y at the end with an ies
<- str_replace(____)
gift
} # Check for a oo (goose)
else if(____){
# Replace the oo with a ee
<- str_replace(____)
gift
} else{
# Add an s to the end of the gift
<- str_c(____)
gift
}
return(gift)
}
Test Your Function
Try your function out on the smaller and then larger gift data set.
## TESTING ON SMALL DATASET
map_chr(.x = xmas_small$gift_item,
.f = ~ pluralize_gift(gift = .x)
)
## TESTING ON LARGE DATASET
map_chr(.x = xmas$gift_item,
.f = ~ pluralize_gift(gift = .x)
)
Step 2 – Creating sentences
Next we will write a function called make_phrase()
that takes as input the necessary information, and returns a phrase. For example,
make_phrase(day_num = 4,
adjective = "calling",
item = "birds",
verb = "",
location = "")
should return
"four calling birds"
and
make_phrase(day_num = 10,
adjective = NA,
item = "lords",
verb = "a-leaping",
location = NA
)
should return
"ten lords a-leaping"
Here are some tips for completing this task:
- You will need to use your
pluralize_gift()
function!
<- function(day_num, adjective, gift, verb, location) {
make_phrase
## Step 1: Replace NAs with empty strings
<- str_replace_na(adjective, replacement = "")
adjective <- ____
____ <- ____
____
## Step 2: Convert numeric day to English day (1 = one, 2 = two)
<- english::as.english(day_num) |>
day_word as.character()
## Step 3: If the day number is larger than 1, the gifts need pluralized!
<- if_else(day_num > 1,
gift
____,
____)
## Step 4: For the first day, replace day_num with "a" or "an"
# Does the item start in a vowel?
<- str_detect(gift, pattern = ____)
begin_vowel
<- case_when(
day_word # If the gift starts with a vowel, add "an" to the beginning
== 1 & begin_vowel ~ ____,
day_num # If the gift DOES NOT start with a vowel, add "a" to the beginning
== 1 & !begin_vowel ~ ____,
day_num ## If the day IS NOT 1, then day_word should default to what was made before
.default = ____
)
## Step 5: Glue all of the pieces together into one string and return!
<- glue("{day_word} {adjective} {gift} {verb} {location}")
phrase
# Step 6: Remove whitespace from gluing the string together
<- str_squish(phrase)
phrase
return(phrase)
}
Test Your Function
Let’s try your function out on the xmas_small
data, by making a new variable containing the daily phrases. Notice I’ve provided you with code to iterate through each row of the data set to create a phrase (using your make_phrase()
function) with your function’s five inputs (day_num
, adjective
, item
, verb
, location
).
Because your function has more than two inputs, we need to use a function from the pmap_XXX()
family. I specifically chose pmap_chr()
because the output of the make_phrase()
function is a character (string).
|>
xmas_small mutate(full_phrase = pmap_chr(.l = list(day_num = day,
adjective = adjective,
gift = gift_item,
verb = verb,
location = location
), .f = make_phrase
) )
Once you’ve obtained a successful test on your xmas_small
dataset, fill in the necessary inputs to pmap_chr()
to create a full_phrase
column in the xmas
dataset.
<- xmas |>
xmas mutate(full_phrase = pmap_chr(.l = list(day_num = ______,
adjective = ______,
gift = ______,
verb = ______,
location = ______
), .f = make_phrase
) )
Canvas Submission
Your
full_phrase
column is the answer to this week’s Practice Activity.Copy and paste your
full_phrase
column to show me the phrases you made!
|>
xmas pull(full_phrase)
If you finished early…
Revise the pluralize_gift()
function to be a vectorized function! Hint, you will need to translate the if()
. else if()
, and else()
code into different cases for the case_when()
function.
Try out your vectorized function!
pluralize_gift(xmas$gift_item)