Welcome to the PSYC3361 coding W3 self test. The test assesses your ability to use the coding skills covered in the Week 3 online coding modules.
In particular, it assesses your ability to…
It is IMPORTANT to document the code that you write so that someone who is looking at your code can understand what it is doing. Above each chunk, write a few sentences outlining which packages/functions you have chosen to use and what the function is doing to your data. Where relevant, also write a sentence that interprets the output of your code.
Your notes should also document the troubleshooting process you went through to arrive at the code that worked.
For each of the challenges below, the documentation is JUST AS IMPORTANT as the code.
Good luck!!
Jenny
PS- if you get stuck have a look in the /images folder for inspiration
I loaded tidyverse, ggplot2 and dplyr. When doing question 5 I discovered the ‘janitor’ package and the ‘tabyl’ function, so I am loading that package here as well.
library(tidyverse)
library(dplyr)
library(janitor)
library(ggplot2)
Creating ‘alone’ object, using ‘<-’ assignment operator and ‘read_csv’function to read the ’alone.csv’ file.
alone <- read_csv("data/alone.csv")
From Jenny: We are mostly interested in gender, age, the days they lasted and whether contestants were medically evacuated. Use select() to make a smaller dataframe containing just the relevant variables. Rename the variable called medically_evacuated to make it shorter and easier to type.
From me: Here I have created the ‘alone_small’ object for the smaller dataframe of the ‘alone’ object. Afterwards, I first used ‘rename’ to change the name from ‘medically_evacuated’ to ‘evac’. Finally, I used ‘select’ to only select the four variables I wanted: ‘gender’, ‘age’, ‘days_lasted’ and ‘evac’. I then ungrouped the variables.
alone_small <- alone %>%
rename(
evac = medically_evacuated
) %>%
select(gender, age, days_lasted, evac
) %>%
ungroup()
From me: I created an object called ‘max_age’ and assigned the ‘alone’ dataset to it. After a pipe I then used ‘group_by’ to group by gender, then a pipe, then ‘summarise’ to summarise based on the maximum age using ‘max()’ and the variable ‘age’.
Previous attempt before I figured out the above much simpler way: I created the object ‘max_male’ and assigned the ‘alone_small’ dataset to it. After a pipe command I then used ‘filter’ to filter by the variable in the dataset ‘gender’, where I used ‘==’ to check that ‘gender’ was equal to “Male”. After another pipe, I used the ‘summarise’ function to summarise the data based on a variable, which I then used the ‘max’ function to check for the maximum value in the data under the ‘age’ variable. After another pipe I then used ‘ungroup’ to ungroup the variables. I did an identical procedure for ‘max_female’. I then used the ‘print’ function to print both ‘max_male’ and max_female’.
max_age <- alone %>%
group_by(gender) %>%
summarise(max(age))
# max_male <- alone_small %>%
# filter(
# gender == "Male"
# ) %>%
# summarise(
# max(age)
# ) %>%
# ungroup()
#
# print(max_male)
#
# max_female <- alone_small %>%
# filter(
# gender == "Female"
# ) %>%
# summarise(
# max(age)
# ) %>%
# ungroup()
#
# print(max_female)
From me: I created the object ‘time_lasted’ from the ‘alone’ dataset. After a pipe I used ‘group_by’ to group by the variable ‘season’, then a pipe and a summarise function. I then summarise two variables I created: ‘mean_time’ which equaled the ‘mean()’ of how many days contestants lasted, and ‘sd_time’, which was the standard deviation for how many days contestants lasted.
After looking at the step below I realised I needed to make a variable for the standard error. I found out about the ‘stderr()’ function, but after some research I saw that I would need to define the function before using it. I also found out that instead I could just use the standard deviation function ‘sd()’, ‘n()’ and the square root formula ‘sqrt()’ to replicate the formula for the standard error. I created the variable ‘n’ using the ‘n()’ function, which would count how many entries there were per season. I then printed ‘time_lasted’.
time_lasted <- alone %>%
group_by(season) %>%
summarise(
mean_time = mean(days_lasted),
sd_time = sd(days_lasted),
n = n(),
se_mean_time = sd_time/sqrt(n)
)
print(time_lasted)
## # A tibble: 9 × 5
## season mean_time sd_time n se_mean_time
## <dbl> <dbl> <dbl> <int> <dbl>
## 1 1 21.6 23.6 10 7.45
## 2 2 34.4 25.0 10 7.89
## 3 3 54.3 30.9 10 9.76
## 4 4 31.4 32.4 14 8.65
## 5 5 30.1 19.4 10 6.14
## 6 6 45.4 28.0 10 8.86
## 7 7 49.9 31.6 10 9.99
## 8 8 41.2 26.6 10 8.40
## 9 9 46.1 21.6 10 6.84
HINT: can you make a line graph that has error bars around the mean for each season?
I needed to turn season into a categorical variable using ‘factor()’. I then made a ggplot using ‘time_lasted’ as the data, with season on the x axis and time_lasted on the y axis. I had to use ‘group = “season”’ for the line to appear, otherwise it was a blank graph. The error bounds of the error bars were calculated using mean +- standard error. I added ‘geom_point’ to better display the mean days lasted for each season and made the points blue for fun. I added the error bars and made the width smaller as it was very large by default. I finally used ‘theme_light’ as it looked nice and was easy to understand. There does seem to be a trend of the mean number of days lasted increasing throughout the seasons. Season 3 seems to be an outlier.
time_lasted$season <- as.factor(time_lasted$season)
picture_season <- ggplot(
data = time_lasted,
mapping = aes(
x = season,
y = mean_time,
group = "season"
)) +
geom_line() +
geom_point(colour = "blue", size = 2) +
geom_errorbar(
aes(
ymin = mean_time - se_mean_time,
ymax = mean_time + se_mean_time,
width = 0.4)
) +
labs(
title = "Mean Number of Days Lasted by Alone Contestants Per Season",
x = "Season",
y = "Days Lasted"
) +
theme_light()
plot(picture_season)
I created a new object ‘mean_gender_time’ and assigned the ‘alone’ dataset to it. Similarly to one of the questions above, I used a pipe then grouped by gender. After another pipe, I summarised based on the mean of ‘days_lasted’, before printing the new object. Women lasted 49,4 days on average, compared to men who lasted 36.2 days on average. It seems that women last approximately 13 days longer than men.
mean_gender_time <- alone %>%
group_by(gender) %>%
summarise(
mean(days_lasted))
print(mean_gender_time)
## # A tibble: 2 × 2
## gender `mean(days_lasted)`
## <chr> <dbl>
## 1 Female 49.4
## 2 Male 36.2
HINT: can you make a plot that captures the median and distribution of days survived, by gender?
I created a box plot to show the median and distribution best, where the x axis was gender and the y axis was days lasted, and to make it have some colour I used ‘fill’ and equaled that to gender. I originally had ‘geom_point’ but all the points stacked on top of each other, and after some research it seemed easier to use ‘geom_jitter’ to make the graph more readable. I used alpha = 1 to make the box plot transparent. I used ‘theme_minimal’ and changed the labels for the title, x and y axis. However, ‘alpha’ kept showing up in the legends section, and after some research I then used the ‘guide’ function and ‘alpha = FALSE’ to remove it from the legends column.
picture_gender_survived <- alone %>%
ggplot(
data = alone,
mapping = aes(
x = gender,
y = days_lasted,
fill = gender,
alpha = 1)
) +
geom_boxplot(
) +
geom_jitter(
width = 0.1,
size = 2
) +
theme_minimal() +
labs(
title = "Distribution of Days Survived Separated by Gender",
x = "Gender",
y = "Days Survived",
fill = "Gender"
) +
guides(
alpha = FALSE
)
## Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as
## of ggplot2 3.3.4.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
plot(picture_gender_survived)
HINT: Use case_when to create a new variable that groups participants by age in decades
I created a new object ‘contestants_age’. I used mutate and created a new variable ‘age_group’ and then ‘case_when’. In ‘case_when’, I used ‘between’, followed with the variable ‘age’ and the limits for the values within age, and then I named each decade. I then used the table function to show me both ‘age’ and ‘age_group’ variables within the ‘contestants_age’ dataset. When using ‘tabyl’, I used the ‘$’ sign to get it to examine the age_group variable within the contestants_age dataset.
contestants_age <- alone %>%
mutate(age_group = case_when(
between(age, 10, 19) ~ "Teens",
between(age, 20, 29) ~ "Twenties",
between(age, 30, 39) ~ "Thirties",
between(age, 40, 49) ~ "Fourties",
between(age, 50, 59) ~ "Fifties",
between(age, 60, 69) ~ "Sixties"
))
tabyl(contestants_age$age_group)
## contestants_age$age_group n percent
## Fifties 6 0.06382979
## Fourties 37 0.39361702
## Sixties 1 0.01063830
## Teens 2 0.02127660
## Thirties 36 0.38297872
## Twenties 12 0.12765957
#I originally had the code below, but it wasn't very easy to read or nice to look at. After discovering the tabyl function, I ditched the code below.
# table(contestants_age$age_group, contestants_age$age)
HINT: what is the mean length of time in the game for each age group? How many participants fall into each group?
I made a new object ‘mean_survival_age’, grouped by the previously created ‘age_group’ variable, the summarised by the average of days lasted. I then made a new variable ‘participants_count’ and the function ‘n()’ to count how many participants were in each age group.
mean_survival_age <- contestants_age %>%
group_by(age_group) %>%
summarise(mean(days_lasted),
participants_count = n())
print(mean_survival_age)
## # A tibble: 6 × 3
## age_group `mean(days_lasted)` participants_count
## <chr> <dbl> <int>
## 1 Fifties 42.2 6
## 2 Fourties 37.1 37
## 3 Sixties 74 1
## 4 Teens 1.5 2
## 5 Thirties 41.4 36
## 6 Twenties 39.7 12
HINT: filter the dataset to keep only those contestants who didn’t win, then calculate the mean age, separately for those who were medically evacuated vs. not.
I created a new object ‘med_evac’ with the alone dataset. I filtered by results greater than 1, grouped by medically_evacuated and gender, before summarising by the average age. It seems that, regardless of gender, those who are medically evacuated are on average younger than those who are not medically evacuated.
med_evac <- alone %>%
filter(result > 1) %>%
group_by(medically_evacuated, gender) %>%
summarise(mean_age = mean(age))
## `summarise()` has grouped output by 'medically_evacuated'. You can override
## using the `.groups` argument.
print(med_evac)
## # A tibble: 4 × 3
## # Groups: medically_evacuated [2]
## medically_evacuated gender mean_age
## <lgl> <chr> <dbl>
## 1 FALSE Female 42.5
## 2 FALSE Male 37.8
## 3 TRUE Female 37.9
## 4 TRUE Male 35.9
HINT: make a column graph of the data you just summarised
I first converted ‘medically_evacuated’ into a factor. I think made a plot where the x-axis was gender and y-axis was average. I filled this plot using ‘medically_evacuated’ with ‘factor’, where I specified the order of “TRUE” and “FALSE” using ‘levels = c’. I used geom_col for a column graph and used ‘position = “dodge”’ so that the columns didn’t stack on top of one another. I used theme_minimal and labelled the title, x axis, y axis and the title of the legend.
med_evac$medically_evacuated <- as.factor(med_evac$medically_evacuated)
picture_med_evac <- med_evac %>%
ggplot(
data = med_evac, mapping = aes(
x = gender,
y = mean_age,
fill = factor(medically_evacuated, levels = c("TRUE", "FALSE"))
)) +
geom_col(position = "dodge") +
labs(
title = "Mean Age of Contestants Who Medically Evacuated vs Not, as a Function of Gender",
x = "Gender",
y = "Mean Age",
fill = "Medically Evacuated"
) +
theme_minimal()
plot(picture_med_evac)