library(tidyverse)

Exercise 1: Parsing data

Part 1: Parsing dates

Generate the correct format string to parse each of the following dates and times:

d1 <- "January 1, 2010"
d2 <- "2015-Mar-07"
d3 <- "06-Jun-2017"
d4 <- c("August 19 (2015) - 3:04PM", "July 1 (2015) - 4:04PM")
d5 <- "12/30/14" # Dec 30, 2014
t1 <- "1705"     # 5:05PM
parse_date(d1, format = "%B %d, %Y")
[1] "2010-01-01"
parse_date(d2, format = "%Y-%b-%d")
[1] "2015-03-07"
parse_date(d3, format = "%d-%b-%Y")
[1] "2017-06-06"
parse_datetime(d4, format = "%B %d (%Y) - %I:%M%p")
[1] "2015-08-19 15:04:00 UTC" "2015-07-01 16:04:00 UTC"
parse_time(t1, format = "%H%M")
17:05:00

Part 2: Read a CSV file

Download this NCHS dataset on leading Causes of death in the United States, from 1999 to 2015: https://data.cdc.gov/api/views/bi63-dtpu/rows.csv.

Then, import it into R. Are some of the colums the wrong type? If not is there any column that could be a factor instead of character type?

df <- read_csv("https://data.cdc.gov/api/views/bi63-dtpu/rows.csv")
Parsed with column specification:
cols(
  Year = col_integer(),
  `113 Cause Name` = col_character(),
  `Cause Name` = col_character(),
  State = col_character(),
  Deaths = col_integer(),
  `Age-adjusted Death Rate` = col_double()
)
df

Execise 2: Data manipulation

Part 1: dplyr verbs

Load in the dataset movies.csv used in the lecture:

url <- "https://raw.githubusercontent.com/Juanets/movie-stats/master/movies.csv"
movies <- read_csv(url)
Parsed with column specification:
cols(
  budget = col_double(),
  company = col_character(),
  country = col_character(),
  director = col_character(),
  genre = col_character(),
  gross = col_double(),
  name = col_character(),
  rating = col_character(),
  released = col_character(),
  runtime = col_integer(),
  score = col_double(),
  star = col_character(),
  votes = col_integer(),
  writer = col_character(),
  year = col_integer()
)
movies
  1. Find a subset of the movies produced after 2010. Save the subset in ‘movies.sub’ variable.
movies.sub <- filter(movies, year > 2010)
movies.sub
  1. Keep columns ‘name’, ‘director’, ‘year’, ‘country’, ‘genre’, ‘budget’, ‘gross’, ‘score’ in the ‘movies.sub’.
movies.sub <- select(movies.sub, name, director, year, country, genre, budget, gross, score)
movies.sub
  1. Find the profit for each movie in ‘movies.sub’ as a fraction of its budget. Convert ‘budget’ and ‘gross’ columns million dollar units founded to the first decimal point. Use round() to round numbers.
movies.sub <- mutate(movies.sub, 
                     frac_profit = (gross - budget)/budget,
                     budget = round(budget/10^6, digits = 1),
                     gross = round(gross/10^6, digits = 1))
movies.sub
  1. Count the number of movies in ‘movies.sub’ produced by each genre, and order them in the descending count order.
by_genre <- group_by(movies.sub, genre)
arrange(summarise(by_genre, count = n()), desc(count))
  1. Now group movies in ‘movies.sub’ by countries and genre. Then, count the number of movies in each group and the corresponding median fractional profit, the mean and standard deviation of the movie score for each group.
movies.summary <- movies.sub %>%
  group_by(genre, country) %>%
  summarise(count = n(), 
            median_profit = median(frac_profit),
            mean_score = mean(score), 
            sd_score = sd(score)) %>%
  filter(count > 10) %>%
  arrange(desc(mean_score))
movies.summary

Part 2: Chaining

Using chaining and pipes, for each genre find the three directors with the top mean movie scores received for the movies produced after 2000, but do not include the directors with fewer than 3 movies in total. Hint: Use top_n() function to select top n from each group.

top5_dir <- movies %>% 
  filter(year > 2000) %>%
  group_by(genre, director) %>%
  summarise(
    mean_score = mean(score),
    count = n()) %>%
  filter(count >= 3) %>%
  group_by(genre) %>%
  top_n(5, wt = mean_score)
top5_dir

Pick your favourite genre and the top 3 directors to find movie recommendations for your next movie night!

class(top5_dir)
[1] "grouped_df" "tbl_df"     "tbl"        "data.frame"

See that top5_dir has a class ‘grouped_df’, so we convert it to a data frame first.

topDramaDir <- top5_dir %>% 
  as_data_frame() %>%
  filter(genre == "Drama") %>% 
  select(director)
movies %>% 
  filter(genre == "Drama", 
         director %in% topDramaDir[["director"]]) %>%
  select(name, director, year, score, genre, gross, budget) %>%
  arrange(desc(score))
LS0tCnRpdGxlOiAiTGVjdHVyZSAzOiBFeGVyY2lzZXMgd2l0aCBBbnN3ZXJzIgpkYXRlOiBPY3RvYmVyIDR0aCwgMjAxOApvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQotLS0KCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBlY2hvID0gRkFMU0UsIGluY2x1ZGUgPSBGQUxTRX0Kb3B0aW9ucyh3aWR0aCA9IDgwKQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCB0aWR5ID0gRkFMU0UsIHNpemUgPSAic21hbGwiKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgoKCiMgRXhlcmNpc2UgMTogUGFyc2luZyBkYXRhCiAKIyMgUGFydCAxOiBQYXJzaW5nIGRhdGVzCiAKCkdlbmVyYXRlIHRoZSBjb3JyZWN0IGZvcm1hdCBzdHJpbmcgdG8gcGFyc2UgZWFjaCBvZiB0aGUgZm9sbG93aW5nIGRhdGVzIGFuZCB0aW1lczoKYGBge3J9CmQxIDwtICJKYW51YXJ5IDEsIDIwMTAiCmQyIDwtICIyMDE1LU1hci0wNyIKZDMgPC0gIjA2LUp1bi0yMDE3IgpkNCA8LSBjKCJBdWd1c3QgMTkgKDIwMTUpIC0gMzowNFBNIiwgIkp1bHkgMSAoMjAxNSkgLSA0OjA0UE0iKQpkNSA8LSAiMTIvMzAvMTQiICMgRGVjIDMwLCAyMDE0CnQxIDwtICIxNzA1IiAgICAgIyA1OjA1UE0KYGBgCgpgYGB7cn0KcGFyc2VfZGF0ZShkMSwgZm9ybWF0ID0gIiVCICVkLCAlWSIpCnBhcnNlX2RhdGUoZDIsIGZvcm1hdCA9ICIlWS0lYi0lZCIpCnBhcnNlX2RhdGUoZDMsIGZvcm1hdCA9ICIlZC0lYi0lWSIpCnBhcnNlX2RhdGV0aW1lKGQ0LCBmb3JtYXQgPSAiJUIgJWQgKCVZKSAtICVJOiVNJXAiKQpwYXJzZV90aW1lKHQxLCBmb3JtYXQgPSAiJUglTSIpCmBgYAoKCiMjIFBhcnQgMjogUmVhZCBhIENTViBmaWxlCgpEb3dubG9hZCB0aGlzIE5DSFMgZGF0YXNldCBvbiBsZWFkaW5nIENhdXNlcyBvZiBkZWF0aCBpbiB0aGUgVW5pdGVkIFN0YXRlcywgZnJvbSAxOTk5IHRvIDIwMTU6IGh0dHBzOi8vZGF0YS5jZGMuZ292L2FwaS92aWV3cy9iaTYzLWR0cHUvcm93cy5jc3YuCgpUaGVuLCBpbXBvcnQgaXQgaW50byBSLiBBcmUgc29tZSBvZiB0aGUgY29sdW1zIHRoZSB3cm9uZyB0eXBlPwpJZiBub3QgaXMgdGhlcmUgYW55IGNvbHVtbiB0aGF0IGNvdWxkIGJlIGEgZmFjdG9yIGluc3RlYWQgb2YgY2hhcmFjdGVyCnR5cGU/CgpgYGB7cn0KZGYgPC0gcmVhZF9jc3YoImh0dHBzOi8vZGF0YS5jZGMuZ292L2FwaS92aWV3cy9iaTYzLWR0cHUvcm93cy5jc3YiKQpkZgpgYGAKCgojIEV4ZWNpc2UgMjogRGF0YSBtYW5pcHVsYXRpb24KCiMjIFBhcnQgMTogYGRwbHlyYCB2ZXJicwoKTG9hZCBpbiB0aGUgZGF0YXNldCBgbW92aWVzLmNzdmAgdXNlZCBpbiB0aGUgbGVjdHVyZToKCmBgYHtyfQp1cmwgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9KdWFuZXRzL21vdmllLXN0YXRzL21hc3Rlci9tb3ZpZXMuY3N2Igptb3ZpZXMgPC0gcmVhZF9jc3YodXJsKQptb3ZpZXMKYGBgCgoKYS4gRmluZCBhIHN1YnNldCBvZiB0aGUgbW92aWVzIHByb2R1Y2VkIGFmdGVyIDIwMTAuIApTYXZlIHRoZSBzdWJzZXQgaW4gJ21vdmllcy5zdWInIHZhcmlhYmxlLgoKYGBge3J9Cm1vdmllcy5zdWIgPC0gZmlsdGVyKG1vdmllcywgeWVhciA+IDIwMTApCm1vdmllcy5zdWIKYGBgCgpiLiBLZWVwIGNvbHVtbnMgJ25hbWUnLCAnZGlyZWN0b3InLCAneWVhcicsICdjb3VudHJ5JywgJ2dlbnJlJywgJ2J1ZGdldCcsICdncm9zcycsICdzY29yZScKaW4gdGhlICdtb3ZpZXMuc3ViJy4KCmBgYHtyfQptb3ZpZXMuc3ViIDwtIHNlbGVjdChtb3ZpZXMuc3ViLCBuYW1lLCBkaXJlY3RvciwgeWVhciwgY291bnRyeSwgZ2VucmUsIGJ1ZGdldCwgZ3Jvc3MsIHNjb3JlKQptb3ZpZXMuc3ViCmBgYAoKYy4gRmluZCB0aGUgcHJvZml0IGZvciBlYWNoIG1vdmllIGluICdtb3ZpZXMuc3ViJyBhcyBhIGZyYWN0aW9uIG9mIGl0cyBidWRnZXQuCkNvbnZlcnQgJ2J1ZGdldCcgYW5kICdncm9zcycgY29sdW1ucyBtaWxsaW9uIGRvbGxhciB1bml0cyBmb3VuZGVkIHRvIHRoZSBmaXJzdCBkZWNpbWFsIHBvaW50LgpVc2UgYHJvdW5kKClgIHRvIHJvdW5kIG51bWJlcnMuCgpgYGB7cn0KbW92aWVzLnN1YiA8LSBtdXRhdGUobW92aWVzLnN1YiwgCiAgICAgICAgICAgICAgICAgICAgIGZyYWNfcHJvZml0ID0gKGdyb3NzIC0gYnVkZ2V0KS9idWRnZXQsCiAgICAgICAgICAgICAgICAgICAgIGJ1ZGdldCA9IHJvdW5kKGJ1ZGdldC8xMF42LCBkaWdpdHMgPSAxKSwKICAgICAgICAgICAgICAgICAgICAgZ3Jvc3MgPSByb3VuZChncm9zcy8xMF42LCBkaWdpdHMgPSAxKSkKbW92aWVzLnN1YgpgYGAKCgpkLiBDb3VudCB0aGUgbnVtYmVyIG9mIG1vdmllcyBpbiAnbW92aWVzLnN1YicgcHJvZHVjZWQgYnkgZWFjaCBnZW5yZSwKYW5kIG9yZGVyIHRoZW0gaW4gdGhlIGRlc2NlbmRpbmcgY291bnQgb3JkZXIuCgpgYGB7cn0KYnlfZ2VucmUgPC0gZ3JvdXBfYnkobW92aWVzLnN1YiwgZ2VucmUpCmFycmFuZ2Uoc3VtbWFyaXNlKGJ5X2dlbnJlLCBjb3VudCA9IG4oKSksIGRlc2MoY291bnQpKQpgYGAKCmUuIE5vdyBncm91cCBtb3ZpZXMgaW4gJ21vdmllcy5zdWInIGJ5IGNvdW50cmllcyBhbmQgZ2VucmUuClRoZW4sIGNvdW50IHRoZSBudW1iZXIgb2YgbW92aWVzIGluIGVhY2ggZ3JvdXAgYW5kIHRoZSBjb3JyZXNwb25kaW5nIAptZWRpYW4gZnJhY3Rpb25hbCBwcm9maXQsIHRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgCnRoZSBtb3ZpZSBzY29yZSBmb3IgZWFjaCBncm91cC4KCmBgYHtyfQptb3ZpZXMuc3VtbWFyeSA8LSBtb3ZpZXMuc3ViICU+JQogIGdyb3VwX2J5KGdlbnJlLCBjb3VudHJ5KSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCksIAogICAgICAgICAgICBtZWRpYW5fcHJvZml0ID0gbWVkaWFuKGZyYWNfcHJvZml0KSwKICAgICAgICAgICAgbWVhbl9zY29yZSA9IG1lYW4oc2NvcmUpLCAKICAgICAgICAgICAgc2Rfc2NvcmUgPSBzZChzY29yZSkpICU+JQogIGZpbHRlcihjb3VudCA+IDEwKSAlPiUKICBhcnJhbmdlKGRlc2MobWVhbl9zY29yZSkpCm1vdmllcy5zdW1tYXJ5CmBgYAoKCiMjIFBhcnQgMjogQ2hhaW5pbmcKClVzaW5nIGNoYWluaW5nIGFuZCBwaXBlcywgZm9yIGVhY2ggZ2VucmUgZmluZCB0aGUgdGhyZWUgZGlyZWN0b3JzIHdpdGggdGhlCnRvcCBtZWFuIG1vdmllIHNjb3JlcyByZWNlaXZlZCBmb3IgdGhlIG1vdmllcyBwcm9kdWNlZCBhZnRlciAyMDAwLCBidXQKZG8gbm90IGluY2x1ZGUgdGhlIGRpcmVjdG9ycyB3aXRoIGZld2VyIHRoYW4gMyBtb3ZpZXMgaW4gdG90YWwuCkhpbnQ6IFVzZSBgdG9wX24oKWAgZnVuY3Rpb24gdG8gc2VsZWN0IHRvcCBuIGZyb20gZWFjaCBncm91cC4KCmBgYHtyfQp0b3A1X2RpciA8LSBtb3ZpZXMgJT4lIAogIGZpbHRlcih5ZWFyID4gMjAwMCkgJT4lCiAgZ3JvdXBfYnkoZ2VucmUsIGRpcmVjdG9yKSAlPiUKICBzdW1tYXJpc2UoCiAgICBtZWFuX3Njb3JlID0gbWVhbihzY29yZSksCiAgICBjb3VudCA9IG4oKSkgJT4lCiAgZmlsdGVyKGNvdW50ID49IDMpICU+JQogIGdyb3VwX2J5KGdlbnJlKSAlPiUKICB0b3Bfbig1LCB3dCA9IG1lYW5fc2NvcmUpCnRvcDVfZGlyCmBgYAoKUGljayB5b3VyIGZhdm91cml0ZSBnZW5yZSBhbmQgdGhlIHRvcCAzIGRpcmVjdG9ycyB0byBmaW5kIG1vdmllIHJlY29tbWVuZGF0aW9ucwpmb3IgeW91ciBuZXh0IG1vdmllIG5pZ2h0IQoKYGBge3J9CmNsYXNzKHRvcDVfZGlyKQpgYGAKClNlZSB0aGF0IGB0b3A1X2RpcmAgaGFzIGEgY2xhc3MgJ2dyb3VwZWRfZGYnLCBzbyB3ZSBjb252ZXJ0IGl0IHRvIAphIGRhdGEgZnJhbWUgZmlyc3QuCmBgYHtyfQp0b3BEcmFtYURpciA8LSB0b3A1X2RpciAlPiUgCiAgYXNfZGF0YV9mcmFtZSgpICU+JQogIGZpbHRlcihnZW5yZSA9PSAiRHJhbWEiKSAlPiUgCiAgc2VsZWN0KGRpcmVjdG9yKQoKYGBgCgpgYGB7cn0KbW92aWVzICU+JSAKICBmaWx0ZXIoZ2VucmUgPT0gIkRyYW1hIiwgCiAgICAgICAgIGRpcmVjdG9yICVpbiUgdG9wRHJhbWFEaXJbWyJkaXJlY3RvciJdXSkgJT4lCiAgc2VsZWN0KG5hbWUsIGRpcmVjdG9yLCB5ZWFyLCBzY29yZSwgZ2VucmUsIGdyb3NzLCBidWRnZXQpICU+JQogIGFycmFuZ2UoZGVzYyhzY29yZSkpCmBgYAoK