Lab 2

Due: end-of-lab Friday September 11

Today, we will be working with data from the first three full seasons of the NC Courage, a highly successful National Women’s Soccer League (NWSL) team located near Duke in Cary, NC. The Courage moved to the Triangle from Western New York in 2017 and had three epic seasons in NC, culminating in winning the championship game that was held at their stadium in Cary in 2019! Data for this lab was sourced from the nwslR package on Github, and verified with the NC Courage website by Meredith Brown (Duke StatSci ’21) in a previous semester.

courage <- read_csv("data/courage.csv")

The courage dataset has 78 rows and 10 variables. Each row is a game, and the variables in the dataset are as follows:

Variable Descripton
game_id An unique ID for the game
game_date Game date
game_number Game number
home_team Name of the home team, abbreviated
away_team Name of the away team, abbreviated
opponent The team NC Courage played against
home_pts Number of points by the home team
away_pts Number of points by the away team
result Result of the game for NC Courage (win, loss, tie)
season Season (2017, 2018, or 2019)

Setup

  1. Log-in to your container;
  2. Double-check that you have the sta101-f26-files project loaded in the upper-right corner of RStudio (this should always be true);
  3. Go to the “Git” tab in the upper-right panel of RStudio and click the Pull button (arrow pointing down). Now the new assignment template and dataset should appear in the lab folder of your Files;
  4. At the top of the new .qmd, in between ---, you have the settings for the document (the so-called YAML, but don’t worry about that). Modify the authors so it lists yourself and your teammates.

Task 1

Create a bar plot of the results of games for NC Courage. Additionally, calculate the numbers of wins, losses, and ties. Write a one sentence narrative for your findings.

Task 2

  1. Create a new variable indicating whether the game was played at home or away for NC Courage. This variable should be called home_courage and take the value “home” if NC Courage is the home team and “away” if NC Courage is the away team. Note: make sure you use variable assignment to store this new variable so you can use it later.
  2. Calculate the number of home and away games, and write a one sentence narrative for your findings.

Say you have this silly data frame:

df
# A tibble: 6 × 2
       x      y
   <dbl>  <dbl>
1 -0.626  0.487
2  0.184  0.738
3 -0.836  0.576
4  1.60  -0.305
5  0.330  1.51 
6 -0.820  0.390

You want to add a new column with the value “apple” if x is positive, and “banana” if x is negative (or zero). The fact that you want to add a column means this is a job for mutate. But how do you achieve this thing where “in this case do one thing, in that case do another”? Use this command

df <- df |>
  mutate(
    z = if_else(x > 0, "apple", "banana")
  )

df
# A tibble: 6 × 3
       x      y z     
   <dbl>  <dbl> <chr> 
1 -0.626  0.487 banana
2  0.184  0.738 apple 
3 -0.836  0.576 banana
4  1.60  -0.305 apple 
5  0.330  1.51  apple 
6 -0.820  0.390 banana

So if_else takes three arguments. The first is a logical condition. It will either be TRUE or FALSE. The second argument is what we should do if the condition is true. The third argument is what we should do if the condition is false.

Task 3

  1. Visualize the relationship between home_courage and result.
  2. Calculate the proportions of home and away games that the Courage won. Based on these, do your findings suggest a home-field advantage? Why or why not?

Task 4

So far we have focused on whether the game was at home or away and whether the Courage won. Next, we dive deeper and focus on the number of points the Courage wins by, at home and away.

How many points do the Courage typically win by (on average)? Use the example code below to get started. You’ll encounter a new function: abs() is the absolute value function. It takes the absolute value of a number. Why do we want to use this absolute value function here?

New command: filter

We are only interested in games the Courage wins, therefore we should filter() for those games first. This is a command that narrows down a data frame by keeping some rows and discarding others. Recall the silly data frame:

df
# A tibble: 6 × 3
       x      y z     
   <dbl>  <dbl> <chr> 
1 -0.626  0.487 banana
2  0.184  0.738 apple 
3 -0.836  0.576 banana
4  1.60  -0.305 apple 
5  0.330  1.51  apple 
6 -0.820  0.390 banana

If we wanted to narrow things down and just consider the banana rows (and honestly, who wouldn’t?), we can say

df |>
  filter(z == "banana")
# A tibble: 3 × 3
       x     y z     
   <dbl> <dbl> <chr> 
1 -0.626 0.487 banana
2 -0.836 0.576 banana
3 -0.820 0.390 banana

So inside filter is a logical condition that determines which rows will be kept. If the condition is true, we keep the row. If it’s false, we throw it out.

Task 5

How many points do NC Courage score when they win (on average)? Note this is different than how many points they “win by”. How many points do the Courage score when they lose on average? To calculate this we first need to determine how many points NC Courage scored in every game. We can use if_else() logic again to find this value for each game, and store it in a new column, courage_pts. Make sure you save your work!

Task 6 (optional)

Next we’ll investigate visually whether or not NC Courage has a home-field advantage. Mutate the courage data frame to create two new variables:

  • total_pts: Sum of points scored by both teams, i.e. home_pts + away_pts.

  • opponent_pts: Points scored by the opposing team, i.e., total_pts - courage_pts.

Save the resulting data frame as courage again and print the three points columns (total_pts, opponent_pts, courage_pts) to screen.

Before when we wanted to discard some rows and keep others, we used filter. If instead you want to discard some columns and discard others, you use select. Recall the silly data frame:

df
# A tibble: 6 × 3
       x      y z     
   <dbl>  <dbl> <chr> 
1 -0.626  0.487 banana
2  0.184  0.738 apple 
3 -0.836  0.576 banana
4  1.60  -0.305 apple 
5  0.330  1.51  apple 
6 -0.820  0.390 banana

If I want to focus just on the first and third columns, then:

df |>
  select(x, z)
# A tibble: 6 × 2
       x z     
   <dbl> <chr> 
1 -0.626 banana
2  0.184 apple 
3 -0.836 banana
4  1.60  apple 
5  0.330 apple 
6 -0.820 banana

So inside select, I list out all of the columns that I wish to keep. The rest are discarded.

Task 7 (optional)

Create a scatter plot:

  • opponent_pts (y) vs. courage_pts (x);
  • Color the scatter plot by whether NC Courage are home or away;
  • Represent the data with “jittered” points using the new layer geom_jitter();
  • Overlay a \(y = x\) line using the new layer geom_abline();
  • Faceted by season using the new layer facet_wrap().

What does the \(y=x\) line represent? What does it mean for a point to fall above the line? What does it mean for a point to fall below the line?

Task 8 (optional)

If we want to formally test whether the Courage have a home-field advantage, then we must first define what this means! In your own words, what do you think a home-field advantage means? Then, now that you’ve defined what it means to have a home field advantage, define what it means to not have a home-field advantage.

Submission

You collaborated with your team, but now everyone submits individually:

  1. Hit the blue Render button to generate your final PDF;
  2. Give your work a final look over to double-check a few things:
    • that your code is stylish;
    • that none of your code or pictures runs off the page. We cannot grade what we cannot read;
    • that all of your plots are well-labeled and human-readable. In other words “Flipper length (mm)” instead of flipper_length_mm;
    • If your work is lacking on any of these items, fix them and re-render as needed;
  3. Download the PDF from your container;
  4. Upload it to Gradescope;
  5. Don’t forget to mark your pages.