MC³ LabCUHK Psychology

Lesson 7 · Working with data

Summarise groups

Turn 300 rows into a few numbers, for everyone or for each group.

In this lesson

  • summarise() a column
  • group_by() to compare groups
  • Put categories in order with factor()

You need

Datastudents.csvStudent Life Survey: 300 students, with their study habits, sleep, stress, wellbeing and exam results.
Scriptlesson-07.RAll the code in this lesson, ready to run.

Set up

R code
library(tidyverse)
students <- read_csv("data/students.csv", show_col_types = FALSE)

summarise(): many rows to one

R code
students %>%
  summarise(n = n(), mean_exam = mean(ExamScore), sd_exam = sd(ExamScore))
Output
# A tibble: 1 × 3
      n mean_exam sd_exam
  <int>     <dbl>   <dbl>
1   300      67.5    13.1

You name each summary. n() counts rows.

group_by(): one summary per group

MotivationExamScore
Low43
Medium73
High88
Medium75
Low67
High70
group_by()→
4367
7375
8870
summarise()→
Motivationmean
Low55
Medium74
High79

Split the rows into groups, summarise each group, put the answers in one table.

R code
students %>%
  group_by(Motivation) %>%
  summarise(n = n(),
            mean_exam = mean(ExamScore),
            mean_study = mean(StudyHours, na.rm = TRUE))
Output
# A tibble: 3 × 4
  Motivation     n mean_exam mean_study
  <chr>      <int>     <dbl>      <dbl>
1 High          87      73.7       17.2
2 Low           66      58.7       11.6
3 Medium       147      67.7       13.3

More motivated students studied more and scored higher. StudyHours has missing values, so it needs na.rm = TRUE.

Put groups in order

Groups come out A to Z (High, Low, Medium). A factor sets your own order:

R code
students <- students %>%
  mutate(Motivation = factor(Motivation, levels = c("Low", "Medium", "High")))

students %>%
  group_by(Motivation) %>%
  summarise(n = n(), mean_exam = mean(ExamScore))
Output
# A tibble: 3 × 3
  Motivation     n mean_exam
  <fct>      <int>     <dbl>
1 Low           66      58.7
2 Medium       147      67.7
3 High          87      73.7

The order also carries into charts.

Two groupings at once

R code
students %>%
  group_by(Workshop, Gender) %>%
  summarise(n = n(), mean_change = mean(Wellbeing_T2 - Wellbeing_T1), .groups = "drop")
Output
# A tibble: 4 × 4
  Workshop Gender     n mean_change
  <chr>    <chr>  <int>       <dbl>
1 No       Female   102      -0.160
2 No       Male      78      -0.210
3 Yes      Female    82       0.436
4 Yes      Male      38       0.614

One row for each combination. .groups = "drop" tidies up the grouping afterwards; without it, dplyr prints a message about it.

Exercises

Exercise 7.1 Dataset: students.csv

Sleep by gender

For female and male students: the number of students, how many skipped Sleep, and the average sleep.

Show answerHide answer
R code
students %>%
  group_by(Gender) %>%
  summarise(n = n(),
            missing = sum(is.na(Sleep)),
            mean_sleep = mean(Sleep, na.rm = TRUE))
Output
# A tibble: 2 × 4
  Gender     n missing mean_sleep
  <chr>  <int>   <int>      <dbl>
1 Female   184       7       6.39
2 Male     116       3       6.45
Exercise 7.2 Dataset: students.csv

Workshop and wellbeing

For students who did and did not take the workshop, find the average wellbeing at T1 and at T2. Who improved?

Show answerHide answer
R code
students %>%
  group_by(Workshop) %>%
  summarise(n = n(), mean_T1 = mean(Wellbeing_T1), mean_T2 = mean(Wellbeing_T2))
Output
# A tibble: 2 × 4
  Workshop     n mean_T1 mean_T2
  <chr>    <int>   <dbl>   <dbl>
1 No         180    4.53    4.34
2 Yes        120    4.29    4.78

Workshop students went up by about half a point; the others went down slightly. Lesson 15 tests this difference.

Key points

  • summarise() turns a column into a number.
  • group_by() first gives one row per group.
  • factor(levels = ) sets the order of groups.