# Loading necessary data R packages
library(tidyverse)
library(lubridate)
Note that for the select all that apply style questions, there was a percentage correction on incorrect answers for some cases. There might be some changes on your mark compared to what is announced on 21st of October.
Correct answer is arrange().
The arrange() function from tidyverse is used to sort a dataset. The base R equivalent is order(). One example is given below
# Example:
data <- tibble(name = c("Alice", "Bob", "Charlie"), value = c(3, 1, 2))
data %>% arrange(value)
## # A tibble: 3 × 2
## name value
## <chr> <dbl>
## 1 Bob 1
## 2 Charlie 2
## 3 Alice 3
# Returns rows sorted by value in ascending order
order() does something similar but not from tidyverse, it is a base R function and needs a different syntax indeed!
data[order(data$value),]
## # A tibble: 3 × 2
## name value
## <chr> <dbl>
## 1 Bob 1
## 2 Charlie 2
## 3 Alice 3
Assume that the dataset visitors_with_nations (from our workshop) has been imported into your environment. What is wrong with the following code? Select one.
filter(visitors_with_nations, n_2021 > 100000, "England")
Problem here is that we have a missing condition variable. In general, the filter() function requires logical conditions. The string “England” evaluates to TRUE in a logical context, but this is not the intended comparison. The correct syntax uses == for equality comparison. The correct format given as below
filter(visitors_with_nations, n_2021 > 100000, nation == "England")
Assume that the dataset visitors_with_nations contains several
columns, including n_2021 and n_2022, and
others.
What will the following code return? Select one.
visitors <- read_csv("data/UK-visitor-numbers.csv")
## Rows: 348 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): attraction, admission, setting, region
## dbl (2): n_2021, n_2022
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
visitors_with_nations <- visitors %>%
mutate(
nation = case_when(
region == "Northern Ireland" ~ "Northern Ireland",
region == "Scotland" ~ "Scotland",
region == "Wales" ~ "Wales",
TRUE ~ "England"
)
)
visitors_with_nations %>% select(-n_2021, -n_2022)
## # A tibble: 348 × 5
## attraction admission setting region nation
## <chr> <chr> <chr> <chr> <chr>
## 1 1066 Battle of Hastings, Abbey and Battlefie… Members O South… Engla…
## 2 Abbey House Museum Charged I Yorks… Engla…
## 3 Abertarff House Free I Scotl… Scotl…
## 4 Alice Holt Forest Free O South… Engla…
## 5 Alloa Tower Members I Scotl… Scotl…
## 6 Anglesey Abbey Members M East … Engla…
## 7 Anne Hathaway's Cottage Charged M West … Engla…
## 8 Arbeia South Sheilds Roman Fort Free M North… Engla…
## 9 Ashmolean Museum Oxford Free I South… Engla…
## 10 Aston Hall Members M West … Engla…
## # ℹ 338 more rows
With this minus sign in front of the variables, the code removes n_2021 and n_2022 from the dataset.
Suppose you run the following code in your R session:
visitors_with_nations <- visitors_with_nations %>%
mutate(growth = n_2022 - n_2021)
followed by a second incomplete snippet of code:
#visitors_with_nations %>%
# ___________(nation) %>%
# summarise(avg_growth = mean(growth, na.rm = TRUE))
To get the average growth for each nation, which function goes in the blank? (Select one)
To calculate statistics by groups (fore each nation), you need to use group_by() before summarise(). The correct form should be
visitors_with_nations %>%
group_by(nation) %>%
summarise(avg_growth = mean(growth, na.rm = TRUE))
## # A tibble: 4 × 2
## nation avg_growth
## <chr> <dbl>
## 1 England 209979.
## 2 Northern Ireland 123486.
## 3 Scotland 95449.
## 4 Wales 24752
In this question the first code snippet should be given like this but not affecting the overall selection from the multiple choices. Please note that this difference.
Suppose visitors_with_nations contains the following columns, among the others: attraction, admission, nation.
Which of the following gives an error message? Select one.
summarise() collapses the dataset to one row per group (or one row total without grouping), losing the admission column. Therefore, filtering on admission after summarise() causes an error.
# Working examples:
visitors_with_nations %>%
filter(admission == "Free") %>%
summarise(n = n())
## # A tibble: 1 × 1
## n
## <int>
## 1 128
visitors_with_nations %>%
group_by(nation) %>%
filter(admission == "Free") %>%
summarise(n = n())
## # A tibble: 3 × 2
## nation n
## <chr> <int>
## 1 England 93
## 2 Northern Ireland 1
## 3 Scotland 34
visitors_with_nations %>%
group_by(nation) %>%
summarise(n = n())
## # A tibble: 4 × 2
## nation n
## <chr> <int>
## 1 England 240
## 2 Northern Ireland 9
## 3 Scotland 97
## 4 Wales 2
But the we got the failure in that format
visitors_with_nations %>%
summarise(n = n()) %>%
filter(admission == "Free")
# Error: object 'admission' not found
The following code calculates, for each nation, the percentage of tourist attractions that offer free admission to all visitors:
visitors_with_nations %>%
group_by(nation) %>%
count(admission) %>%
mutate(pct = 100 * n / sum(n)) %>%
filter(admission == "Free")
## # A tibble: 3 × 4
## # Groups: nation [3]
## nation admission n pct
## <chr> <chr> <int> <dbl>
## 1 England Free 93 38.8
## 2 Northern Ireland Free 1 11.1
## 3 Scotland Free 34 35.1
Consider this alternative code:
visitors_with_nations %>%
group_by(admission, nation) %>%
summarise(n = n()) %>%
mutate(pct = 100 * n / sum(n)) %>%
filter(admission == "Free")
## `summarise()` has grouped output by 'admission'. You can override using the
## `.groups` argument.
## # A tibble: 3 × 4
## # Groups: admission [1]
## admission nation n pct
## <chr> <chr> <int> <dbl>
## 1 Free England 93 72.7
## 2 Free Northern Ireland 1 0.781
## 3 Free Scotland 34 26.6
Does this alternative code produce the same output as the reference code? If not, why? Select one.
Correct answer is “No, because the percentage is computed within each admission group (across nations), not within each nation.”
The reference code groups by nation before counting, so the percentage is calculated within each nation. The alternative groups by admission first, so the percentage is calculated across nations for each admission type.
You have this data set when you run this in R (explored in Quiz 2 as well)
library(tidyverse)
us_rent_income
## # A tibble: 104 × 5
## GEOID NAME variable estimate moe
## <chr> <chr> <chr> <dbl> <dbl>
## 1 01 Alabama income 24476 136
## 2 01 Alabama rent 747 3
## 3 02 Alaska income 32940 508
## 4 02 Alaska rent 1200 13
## 5 04 Arizona income 27517 148
## 6 04 Arizona rent 972 4
## 7 05 Arkansas income 23789 165
## 8 05 Arkansas rent 709 5
## 9 06 California income 29454 109
## 10 06 California rent 1358 3
## # ℹ 94 more rows
The us_rent_income dataset contains such columns:
What happens if you run
us_rent_income %>%
summarise(avg_variable = mean(variable, na.rm = TRUE))
Select one.
Correct answer is “The code prints a warning:”argument is not numeric or logical: returning NA”
The variable column contains character values (“income” or “rent”), not numeric values. The mean() function cannot compute the mean of character strings.
us_rent_income %>%
summarise(avg_variable = mean(variable, na.rm = TRUE))
# Produces
Which of the following expressions will select only the rows in us_rent_income where the variable is income and the estimate value is more than 20000? Select all that apply.
The correct answers are
us_rent_income %>%
filter(variable == "income" & estimate > 20000)
# And
us_rent_income %>%
filter(estimate > 20000) %>%
filter(variable == "income")
Both correctly filter for rows where variable is “income” AND estimate is greater than 20000.
Option
us_rent_income %>%
filter(variable == "income" | estimate > 20000)
uses OR (|) which would include rows where either condition is true.
us_rent_income %>%
filter(estimate > 20000) %>%
select(variable == "income")
incorrectly tries to use select() with a logical condition.
In which of the following objects is the first element a number (double)? Select all that apply.
Correct answers are;
list(1, "b", TRUE)
## [[1]]
## [1] 1
##
## [[2]]
## [1] "b"
##
## [[3]]
## [1] TRUE
typeof(list(1, "b", TRUE)[[1]])
## [1] "double"
# and
c(1, 2, 5)
## [1] 1 2 5
typeof(c(1,2,5)[1])
## [1] "double"
# Counterexamples:
c(1, "a", TRUE)[1] # Returns 1 (but the vector becomes character because of "a" item)
## [1] "1"
list("1", 3.5, TRUE)[[1]] # Returns "1" as character
## [1] "1"
Match each expression to its result (each answer matches to exactly one expression).
Correct matches are;
FALSE & TRUE
## [1] FALSE
TRUE & NA
## [1] NA
You have the following two tibbles:
vis <- tibble(
attraction = c("Castle", "Museum", "Park", "Zoo"),
n_2022 = c(150000, 125000, 70000, 90000)
)
info <- tibble(
attraction = c("Castle", "Museum", "Park", "Aquarium"),
admission = c("Charged", "Free", "Free", "Charged")
)
You join them using
vis %>% inner_join(info, by = "attraction")
## # A tibble: 3 × 3
## attraction n_2022 admission
## <chr> <dbl> <chr>
## 1 Castle 150000 Charged
## 2 Museum 125000 Free
## 3 Park 70000 Free
Which ones of the following code snippets produce the same output? Select all that apply.
Correct options are;
vis %>% full_join(info, by = "attraction") %>%
drop_na()
## # A tibble: 3 × 3
## attraction n_2022 admission
## <chr> <dbl> <chr>
## 1 Castle 150000 Charged
## 2 Museum 125000 Free
## 3 Park 70000 Free
vis %>% left_join(info, by = "attraction") %>%
drop_na()
## # A tibble: 3 × 3
## attraction n_2022 admission
## <chr> <dbl> <chr>
## 1 Castle 150000 Charged
## 2 Museum 125000 Free
## 3 Park 70000 Free
The others are returning different format outputs
vis %>% full_join(info, by = "attraction")
## # A tibble: 5 × 3
## attraction n_2022 admission
## <chr> <dbl> <chr>
## 1 Castle 150000 Charged
## 2 Museum 125000 Free
## 3 Park 70000 Free
## 4 Zoo 90000 <NA>
## 5 Aquarium NA Charged
vis %>% semi_join(info, by = "attraction")
## # A tibble: 3 × 2
## attraction n_2022
## <chr> <dbl>
## 1 Castle 150000
## 2 Museum 125000
## 3 Park 70000
For this given data,
vis <- tibble(attraction = c("Castle", "Museum", "Park", "Zoo"),
n_2021 = c(130000, 110000, 75000, 80000),
n_2022 = c(150000, 125000, 70000, 90000) )
You use the following code snippet to transform the data:
vis %>%
pivot_longer( cols = c(n_2021, n_2022),
names_to = "year",
values_to = "visitors" )
## # A tibble: 8 × 3
## attraction year visitors
## <chr> <chr> <dbl>
## 1 Castle n_2021 130000
## 2 Castle n_2022 150000
## 3 Museum n_2021 110000
## 4 Museum n_2022 125000
## 5 Park n_2021 75000
## 6 Park n_2022 70000
## 7 Zoo n_2021 80000
## 8 Zoo n_2022 90000
Correct answer are “The output has 3 columns: attraction, year and visitors” and “Each attraction appears twice in the output”
The “year” column will be of type numeric. is not correct since the year column type is character, also it does not include solely 2021 and 2022 by the nature of data. It contains \(n_2021\) and \(n_2022\) here
This is the subset of billboard data from tidyverse if we look at it briefly as below
library(tidyverse)
df_bilboard <- billboard %>% select(artist, track, date.entered, wk1, wk2, wk3)
df_bilboard
## # A tibble: 317 × 6
## artist track date.entered wk1 wk2 wk3
## <chr> <chr> <date> <dbl> <dbl> <dbl>
## 1 2 Pac Baby Don't Cry (Keep... 2000-02-26 87 82 72
## 2 2Ge+her The Hardest Part Of ... 2000-09-02 91 87 92
## 3 3 Doors Down Kryptonite 2000-04-08 81 70 68
## 4 3 Doors Down Loser 2000-10-21 76 76 72
## 5 504 Boyz Wobble Wobble 2000-04-15 57 34 25
## 6 98^0 Give Me Just One Nig... 2000-08-19 51 39 34
## 7 A*Teens Dancing Queen 2000-07-08 97 97 96
## 8 Aaliyah I Don't Wanna 2000-01-29 84 62 51
## 9 Aaliyah Try Again 2000-03-18 59 53 38
## 10 Adams, Yolanda Open My Heart 2000-08-26 76 76 74
## # ℹ 307 more rows
Which of the following describes the output given by this code snippet? Select one.
df_bilboard %>%
drop_na(wk1) %>%
drop_na(wk2) %>%
mutate(change = wk1 - wk2) %>%
filter(change > 10)
## # A tibble: 108 × 7
## artist track date.entered wk1 wk2 wk3 change
## <chr> <chr> <date> <dbl> <dbl> <dbl> <dbl>
## 1 3 Doors Down Kryptonite 2000-04-08 81 70 68 11
## 2 504 Boyz Wobble Wobble 2000-04-15 57 34 25 23
## 3 98^0 Give Me Just One N… 2000-08-19 51 39 34 12
## 4 Aaliyah I Don't Wanna 2000-01-29 84 62 51 22
## 5 Aguilera, Christina I Turn To You 2000-04-15 50 39 30 11
## 6 Aguilera, Christina What A Girl Wants 1999-11-27 71 51 28 20
## 7 Alice Deejay Better Off Alone 2000-04-08 79 65 53 14
## 8 Anthony, Marc You Sang To Me 2000-02-26 77 54 50 23
## 9 Avant Separated 2000-04-29 62 32 30 30
## 10 BBMak Back Here 2000-04-29 99 86 60 13
## # ℹ 98 more rows
The correct answer is
“A data frame containing only the songs that moved up the chart by more than 10 places between week 1 and week 2”
The code:
By definition, the difference can be positive or negative but we are only interested in positive values that are greater than 10.
You want to calculate the mean chart position in week 2 for each artist, but the following code does not produce the desired output. Why? Select one.
df_bilboard %>%
summarise(mean_wk2 = mean(wk2, na.rm = TRUE))
## # A tibble: 1 × 1
## mean_wk2
## <dbl>
## 1 71.2
Correct answer is “Because group_by(artist) is missing”
The summarise() function without group_by() calculates a single summary statistic for the entire dataset. To calculate statistics by each artist, you need to group_by(artist) first.