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. (https://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song))
These gifts repeat and compound; on the first day, the narrator recieves
A partridge in a pear tree.
On the last day, he or she receives
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
Your task will be to help write a package that automatically sings this very repetitive song.
Go to https://github.com/Adventures-R/twelvedays to find the package for this week’s lab.
Fortunately, I have already created the main structure of the package for you. Unfortunately, the functions in the package are not complete.
Your job is to fill out the rest of the code inside the functions.
To get your own copy of the package repository, you’ll want to fork it from the Adventures-R
account. You can then clone the repository; i.e., download a copy to your local machine. You can do this via GitHub Desktop (recommended!) or by downloading and unzipping a compressed file.
Once you have downloaded the repository folder, double-click the .Rproj
file inside to launch your R Project.
Run the code below to load up a dataset called xmas
that contains the crucial information about the gifts in the song. We will use this dataset to test out our functions as we work on them.
Note that your functions can - and should! - reference each other.
That is, don’t duplicate code; use earlier, smaller functions inside your larger functions.
The packages dplyr
, stringr
, glue
, and purrr
are already imported into the twelvedays
package, so you can use functions from these without worrying.
If you want to rely on functions from other packages that’s fine, but you need to deal with two fiddly steps:
usethis::use_package("packagename")
into the console.@import packagename
in the top section of each .R
file.Other than this quirk, you do not need to edit any of the package files or documentation in twelvedays
.
A function in a package is no different than any other function. I suggest you make an R Markdown file just for yourself, while you work on designing your functions and testing them on small examples.
Once you feel confident in your function code, copy your work into the appropriate files in the twelvedays
package folder.
Make sure that after each function is finished, you commit your work to Git. (You do not need to push to GitHub until you are done with everything.)
If you have some trouble getting started, I recommend writing a function that works in one case, and then trying to generalize.
For example, in building my sing_day
function, I might first write a version called sing_third_day
that sings
On the third day of Christmas, my true love gave to me:
three french hens,
two turtle doves,
and a patridge in a pear tree.
There’s a lot you can do to polish up the way the song prints.
However, the goal of this lab is to practice writing functions and using iteration. Don’t get bogged down in details like how the song displays, or small grammar rules, until you’ve finished the main tasks.
Note that the gifts are listed in singular: for example, on day 5 the narrator receives “5 golden rings”, but the entry in the dataset for the gift on day 5 simply says “ring”.
In your twelvedays
package, navigate to the file pluralize_gift.R
in the R
folder. You will find some incomplete code for a function called pluralize_gift
that takes a gift and returns the appropriate plural.
Complete this function code.
Try your function out on the gifts in the dataset.
(Consider: is your function vectorized?
It does not have to be, but it may make things simpler!)
Hint 1: Note that the gifts on days 6 and 9 have unusual pluralizations. You may assume that in other datasets, there will be no special cases besides these types.
Hint 2: The following small example may be useful to you:
my_names <- c("Kimberly", "Trini", "Jason", "Billy", "Zach", "Tommy")
my_names %>%
str_replace("y$", "ies")
## [1] "Kimberlies" "Trini" "Jason" "Billies" "Zach"
## [6] "Tommies"
Important: You should absolutely not “hard-code” anything into this function; this function should work in general, not just for the items in the 12 Days of Christmas. For example, the word “rings” should not appear anywhere in the function. I should be able to give it any gift and any day, and get back the plural.
Write a function called make_phrase
that takes as input the necessary information, and returns a phrase. For example,
make_phrase(num = 10,
num_word = "ten",
item = "lords",
verb = "a-leaping",
adjective = "",
location = "")
should return
"ten lords a-leaping"
Try your function out on the xmas
data, by making a new variable containing the daily phrases.
Write a function called sing_line
that takes as input:
A dataset
A number indicating which day to sing about
The name of a column in the dataset that contains the phrases for each day.
For example,
should return
On the second day of Christmas, my true love sent to me,
two turtle doves
and a partridge in a pear tree.
Hint: This function will need a map
function inside of it, to iterate over all the gifts that are given on a particular day.
Hint 2: The {{phrase_col}}
part, which I provided for you, lets you use column names as arguments to a function. Don’t delete that line of code!
Once you are done with all the functions, make sure you have pushed your work to GitHub.
In your console, type
If it prompts you to update packages, I recommend skipping that for now.
Create a new R Markdown file. At the top, include:
Also include a url to your GitHub repository.
Use the following code to load a dataset that is different from the original xmas
song.
Use the functions from your package to print out the whole song from the xmas2
dataset.
Knit your html, and turn it in.
Major points will be deducted for:
A package that cannot be installed
Functions that do not work the way they are intended
“Hard-Coding” in functions.
Not using map
or apply
for iteration.
Not singing the full song. Remember, each day, you get the gift for that day and all the prior days.
Minor points will be deducted for:
Song output that displays in unappealing ways (e.g. extraneous output, extra white space, etc.)
Minor warning messages from functions
Forgetting to include the url to your GitHub repo
No points will be deducted for:
Unvectorized functions
Anything to do with the package files, apart from the functions themselves.
Add a unit test to your package.
This blog post should help you get started.
Create at least one unit test for each of your three functions.