Lecture 2: Data Manipulation with dplyr

STAT 545 - Fall 2026

Learning Objectives

From this topic, students are anticipated to be able to:

  1. Use the five core dplyr verbs for data wrangling: select(), filter(), arrange(), mutate(), summarise().

  2. Use piping when implementing function chains.

  3. Use group_by() to operate within groups (of rows) with mutate() and summarise().

  4. Use across() to operate on multiple columns with summarise() and mutate().

Why Data Manipulation?

  • In practice, it’s very rare that you have the data in the exact right form to make the graph you want, or fit the model you want.

  • You will need to start by manipulating your data into the right form: creating new variables, subsetting rows, renaming columns, etc.

  • An even less exciting but perhaps even more important part of data analysis is simply checking the data for things like:

    • Possible inconsistencies with your understanding of what the data set should contain

    • Possible errors

    • Basic info gathering: number of rows, number of columns, amount of missing data, etc.

Tibbles

  • A tibble is a modern version of a basic data frame.

  • To use tibbles, we first install the tibble package (if we haven’t already) and load it into R by:

Tibbles

  • Tibbles typically said to be more user friendly than standard R dataframes, and are easily used with tidyverse functions. More on that in a bit!

  • We can either load in pre-existing data frames (like from a .csv file or an R package), or create a tibble manually using the tibble() function. For example, we could use

to have a single column tibble of letters of the alphabet, or

Tibbles

  • We can see that the tibble can store different data types (here we have both numeric data (“dbl” is short for double) and character data (“chr” is short for character).

  • We can also change an R data frame to a tibble. For example, the mtcars data set is available in the datasets package in R as a dataframe. We can load it as a tibble using:

dplyr Functions

To use the dplyr functions, we need to install (if necessary) and load the dplyr package:

Once loaded, we will have a number of new tools at our disposal.

dplyr Functions

Subsetting with select()

select() allows you to keep or remove columns.

  • For example, in the housingdata dataset, say we only want the columns name and city. We use the select function where the first argument is the name of the tibble, and the other arguments are the names of the columns we wish to keep:

dplyr Functions

Subsetting with select()

Now, this didn’t alter the original data frame! If we wanted to save this reduced dataframe, we can name it to a new variable, such as

Now, housingdata2 contains only the rows we were interested in keeping, without overriding the original housingdata tibble. We can see that housingdata still contains all of the information from the original data set.

dplyr Functions

Subsetting with select()

We can also use select() to indicate which columns to remove. For example, if I wanted all variables except name in my data set, I could do:

dplyr Functions

Subsetting with filter()

The filter() function allows you to specify which rows to keep in the tibble. The filter() function takes conditional statements and allows us to remove or keep rows based on these conditions.

For example, let’s say we wanted to keep only data where the rent in 2025 (rent_2025) is strictly larger than 2500. Then, we could use:

Now, only rows with rent_2025 > 2500 are kept in the data frame.

dplyr Functions

Subsetting with filter()

We can also use the == sign to indicate that something is equivalent. For example, we may only be interested in observations in Vancouver. To do so, we can use:

Note

The double == in the statement to indicate “is equal to”! Further, as the variable of interest is a string (or character type), we need to use quotations around the city name “Vancouver”.

dplyr Functions

Subsetting with filter()

We can also filter on multiple variables at the same time, even if they are different types. for example:

dplyr Functions

Leveling Up with tidyselect()

  • Sometimes we will want to select columns that have something in common with their name. This is particularly useful when the number of columns is large (for example, think if we had historical rent data for many years).

  • To do so, we can use helper functions in the tidyverse library. First, install (if necessary) and load in the tidyverse library

dplyr Functions

Leveling Up with tidyselect()

Let’s use the starts_with() function to select all columns that relate to rents. We can do this by:

This code returned a tibble where only the columns involving rents are included!

dplyr Functions

Leveling Up with tidyselect()

Other useful helper functions include:

  • starts_with() finds variables that start with the given input

  • ends_with() finds variables that end with the given input

  • contains() finds variables that have the given input at any location in the name

While for the example data set we are really only selecting two columns, using these functions allows your code to be more flexible as data may be added later for more years of rent, for example.

dplyr Functions

Creating New Variables with mutate()

  • Sometimes we need to create another variable or column based on information already present in a tibble.

  • For example, suppose we are interested in the cost per room, rather than total rent, in our data. We can create a new variable that is the rent divided by the number of rooms using mutate():

dplyr Functions

Creating New Variables with mutate()

We can also clean this up by rounding our new variable to two decimal places using the round() function:

As we can see, the mutate() function took the data as the first argument, and then we listed the new variable name rent_per_room_2025 which we calculated by taking the rent in 2025 (rent_2025) and dividing it by the number of rooms in the house (numrooms). We wrapped round( x, 2) around the calculation to clean up the answer to two decimal places.

dplyr Functions

The Pipe Operator %>%

The pipe operator (%>%) is a convenient way to form a chain of commands on a tibble to perform multiple tasks at once.

Let’s say we want to subset our data and select only the rent and city columns on a tibble. We could use:

which is a perfectly valid answer. However, we could also use the pipe operator, as:

Here, we tell dplyr the tibble we want to transform (housingdata), and then use the pipe operator (%>%) to tell dplyr what functions we want to perform on it.

Note

When using the pipe operator, we no longer need to include the dataframe in the first argument of the function. Compare the previous two code chunks to see what I mean.

dplyr Functions

The Pipe Operator %>%

While it may not be obvious from this first example why the pipe operator is commonly used, let’s consider that we want to

  • filter on rents for 2025 above $2500

  • select all columns aside from name

  • create a new variable for the rent per room in 2025 (rounded to 2 decimal places)

  • reorder the rows by descending order of 2025 rents

    • The arrange() function can change the order of rows.

    • arrange(desc(column_name)) will arrange the rows in descending order for the column_name given. See more here!

Fill in the following code to complete the above task:

Note

After each function call, we need to include the pipe operator to tell dplyr that we’re not done yet, and the chain of commands continues on the next line.

dplyr Functions

The Pipe Operator %>%

Another thing to note is that the pipe operator creates a new tibble and does not alter the original. So, housingdata still contains all of the original rows and columns in its unaltered form. If we wanted to alter it (or save the output to a new variable), we need to assign it using <-. For example, the following code will overwrite the original tibble:

Worksheet A2

Worksheet A2 is now available, and will guide you through some of the basics of dplyr.

To Save These Slides With Your Code

To Print to PDF (with your code!), do the following:

  • Open the in-browser print dialog CMD/CTRL + P or Right click > Print

  • Change the Destination setting to Save as PDF.

  • Change the Layout to Landscape.

  • Change the Margins to None. Enable the Background graphics option.

  • Click Save 🎉

In all cases, ensure the code chunks don’t get cut off (i.e., a line is too long). You will not be able to edit these from the PDF directly (though you could open the slides again and copy-and-paste to re-run the code!)