R for Bioinformatics

Lesson 8 of 14 · 10 min

Summarising and Grouping

Raw data usually has one row for every single measurement, which is far too much detail to read at a glance. Summarising means collapsing many rows into a few numbers, such as an average or a count. The dplyr package gives you short, readable commands to do exactly this.

r
library(dplyr)  # load the dplyr package, which gives us data tools and the pipe

# tibble() builds a tidy table; each argument you pass becomes one column
experiment <- tibble(
  sample_id = 1:8,                                  # a number labelling each sample
  treatment = c("control", "control", "control", "control",
                "drug", "drug", "drug", "drug"),    # which group each sample belongs to
  viability = c(98, 95, 97, 96, 62, 58, 65, 60)     # percent of cells still alive
)

experiment  # typing the name on its own line prints the table
# A tibble: 8 × 3
  sample_id treatment viability
      <int> <chr>         <dbl>
1         1 control          98
2         2 control          95
3         3 control          97
4         4 control          96
5         5 drug             62
6         6 drug             58
7         7 drug             65
8         8 drug             60

The symbol %>% is called the pipe, and it passes the table on its left into the function on its right. The summarise() function turns whole columns into single values, and you name each result on the left of an equals sign. Here mean() gives the average, sd() gives the standard deviation (a measure of how spread out the numbers are), and n() counts how many rows went into the calculation.

r
experiment %>%                        # take the experiment table, then...
  summarise(
    mean_viability = mean(viability),  # the average of the viability column
    sd_viability = sd(viability),      # the spread around that average
    n = n()                            # how many rows were counted
  )
# A tibble: 1 × 3
  mean_viability sd_viability     n
           <dbl>        <dbl> <int>
1           78.9         19.0     8

One row for the whole table hides the fact that control and drug samples behave very differently. group_by() marks a column as a grouping key, so the summarise() that follows runs once per category instead of once for everything. When you only need the row count per group, count() is a shortcut that does the grouping and counting in a single step.

r
experiment %>%
  group_by(treatment) %>%              # handle each treatment value separately
  summarise(
    mean_viability = mean(viability),
    sd_viability = sd(viability),
    n = n()
  )
# A tibble: 2 × 4
  treatment mean_viability sd_viability     n
  <chr>              <dbl>        <dbl> <int>
1 control             96.5         1.29     4
2 drug                61.2         2.99     4
r
experiment %>% count(treatment)        # quick count of rows in each treatment
# A tibble: 2 × 2
  treatment     n
  <chr>     <int>
1 control       4
2 drug          4

Try it yourself: Using the experiment tibble, write experiment %>% group_by(treatment) %>% summarise() that reports the middle value with median(viability) and the number of rows with n(). Then run experiment %>% count(treatment) and check that its counts match the n column in your grouped summary.