Choosing things in dataframes

Packages

The usual:

library(tidyverse)

Doing things with data frames

Let’s go back to our Australian athletes:

athletes

Choosing a column

athletes %>% select(Sport)

Choosing several columns

athletes %>% select(Sport, Hg, BMI)

Choosing consecutive columns

athletes %>% select(Sex:WCC, BMI)

Choosing all-but some columns

athletes %>% select(-(RCC:LBM))

Select-helpers

Other ways to select columns: those whose name:

  • starts_with something
  • ends_with something
  • contains something
  • matches a “regular expression”
  • everything() select all the columns

Columns whose names begin with S

athletes %>% select(starts_with("S"))

Columns whose names end with C

either uppercase or lowercase:

athletes %>% select(ends_with("c"))

Case-sensitive

This works with any of the select-helpers:

athletes %>% select(ends_with("C", ignore.case=FALSE))

Column names containing letter R

athletes %>% select(contains("r"))

Exactly two characters, ending with T

In regular expression terms, this is ^.t$:

  • ^ means “start of text”
  • . means “exactly one character, but could be anything”
  • t means a literal letter t (uppercase or lowercase)
  • $ means “end of text”.

Matching a regular expression

athletes %>% select(matches("^.t$"))

Choosing columns by property

  • Use where as with summarizing several columns
  • eg, to choose text columns:
athletes %>% select(where(is.character))

Choosing rows by number

athletes %>% slice(16:25)

Non-consecutive rows

athletes %>% 
  slice(10, 13, 17, 42)

A random sample of rows

athletes %>% slice_sample(n=8)

Rows for which something is true

athletes %>% filter(Sport == "Tennis")

Rows for which something is not true

athletes %>% filter_out(Sport == "Tennis")

More complicated selections

Athletes who are tennis players and whose RCC is less than 5:

athletes %>% filter(when_all(
  Sport == "Tennis",
  RCC < 5
))

Either/Or

Athletes that are either tennis players or whose RCC is greater than 5:

athletes %>% filter(when_any(
  Sport == "Tennis",
  RCC > 5
))

Even more complicated

Females whose RCC is bigger than 5, or males whose RCC is bigger than 6:

athletes %>% 
  filter(when_any(
    when_all(
      Sex == "female",
      RCC > 5
    ),
    when_all(
      Sex == "male",
      RCC > 6
    )
  ))

The results

Sorting into order

athletes %>% arrange(RCC)

Breaking ties by another variable

athletes %>% arrange(RCC, BMI)

Descending order

athletes %>% arrange(desc(BMI))

“The top ones”

athletes %>%
  arrange(desc(Wt)) %>%
  slice(1:7) %>%
  select(Sport, Wt)

Another way

athletes %>% 
  slice_max(order_by = Wt, n=7) %>% 
  select(Sport, Wt)

Create new variables from old ones

athletes %>% 
  mutate(wt_lb = Wt * 2.2) %>% 
  select(Sport, Sex, Wt, wt_lb) %>% 
  arrange(Wt) 

Turning the result into a number

Output is always data frame unless you explicitly turn it into something else, eg. the weight of the heaviest athlete, as a number:

athletes %>% arrange(desc(Wt)) %>% pluck("Wt", 1) -> heavy
heavy
[1] 123.2

Or the 20 heaviest weights in descending order:

athletes %>%
  arrange(desc(Wt)) %>%
  slice(1:20) %>%
  pluck("Wt")
 [1] 123.20 113.70 111.30 108.20 102.70 101.00 100.20  98.00  97.90  97.90
[11]  97.00  96.90  96.30  94.80  94.80  94.70  94.70  94.60  94.25  94.20

To find the mean height of the women athletes

Two ways:

athletes %>% group_by(Sex) %>% summarize(m = mean(Ht))
athletes %>%
  filter(Sex == "female") %>%
  summarize(w_mean = mean(Ht))

Summary of data selection/arrangement “verbs”

Verb Purpose
select Choose columns
slice Choose rows by number
slice_sample Choose random rows
slice_max Choose rows with largest values on a variable (also slice_min)
filter Choose rows satisfying conditions
arrange Sort in order by column(s)
mutate Create new variables
group_by Create groups to work with
summarize Calculate summary statistics (by groups if defined)
pluck Extract items from data frame
pull Extract a single column from a data frame as a vector