Subset a dataframe

There are lots of different ways to subset a dataframe, depending on the kind of output you want.

We’ll illustrate using the msleep dataset that comes from tidyverse. msleep contains some data about how much different kinds of mammals sleep. Here’s what the first few rows of msleep look like.

msleep |> head()
# A tibble: 6 × 11
  name    genus vore  order conservation sleep_total sleep_rem sleep_cycle awake
  <chr>   <chr> <chr> <chr> <chr>              <dbl>     <dbl>       <dbl> <dbl>
1 Cheetah Acin… carni Carn… lc                  12.1      NA        NA      11.9
2 Owl mo… Aotus omni  Prim… <NA>                17         1.8      NA       7  
3 Mounta… Aplo… herbi Rode… nt                  14.4       2.4      NA       9.6
4 Greate… Blar… omni  Sori… lc                  14.9       2.3       0.133   9.1
5 Cow     Bos   herbi Arti… domesticated         4         0.7       0.667  20  
6 Three-… Brad… herbi Pilo… <NA>                14.4       2.2       0.767   9.6
# ℹ 2 more variables: brainwt <dbl>, bodywt <dbl>

Extracting cells

Square-bracket indexing

In computer programming, an “index” is a number that tells you what position some element is in. For example, a row with index 1 is the first row in the dataframe; a column with index 3 is the third column in the dataframe. And where those two intersect, in row 1 and column 3, there is one cell of the dataframe.

As for the “square bracket” part: you can name a dataframe (e.g., my_df), then write an opening square bracket [, write the row index you want, then a comma ,, then the column index you want, the finish by writing the closing square bracket ].

For example, to get the cell in the first row and the third column of msleep:

msleep[1, 3]
# A tibble: 1 × 1
  vore 
  <chr>
1 carni

Extracting column(s)

Dollar-sign notation

Use this method if you want to quickly grab one single column and treat it as a vector.

In dollar-sign notation, we write the name of the dataframe (e.g., my_df), a dollar sign $, then the name of the column we want to extract(e.g., my_column): my_df$my_column.

For example, to get the column name from msleep:

msleep$name
 [1] "Cheetah"                        "Owl monkey"                    
 [3] "Mountain beaver"                "Greater short-tailed shrew"    
 [5] "Cow"                            "Three-toed sloth"              
 [7] "Northern fur seal"              "Vesper mouse"                  
 [9] "Dog"                            "Roe deer"                      
[11] "Goat"                           "Guinea pig"                    
[13] "Grivet"                         "Chinchilla"                    
[15] "Star-nosed mole"                "African giant pouched rat"     
[17] "Lesser short-tailed shrew"      "Long-nosed armadillo"          
[19] "Tree hyrax"                     "North American Opossum"        
[21] "Asian elephant"                 "Big brown bat"                 
[23] "Horse"                          "Donkey"                        
[25] "European hedgehog"              "Patas monkey"                  
[27] "Western american chipmunk"      "Domestic cat"                  
[29] "Galago"                         "Giraffe"                       
[31] "Pilot whale"                    "Gray seal"                     
[33] "Gray hyrax"                     "Human"                         
[35] "Mongoose lemur"                 "African elephant"              
[37] "Thick-tailed opposum"           "Macaque"                       
[39] "Mongolian gerbil"               "Golden hamster"                
[41] "Vole "                          "House mouse"                   
[43] "Little brown bat"               "Round-tailed muskrat"          
[45] "Slow loris"                     "Degu"                          
[47] "Northern grasshopper mouse"     "Rabbit"                        
[49] "Sheep"                          "Chimpanzee"                    
[51] "Tiger"                          "Jaguar"                        
[53] "Lion"                           "Baboon"                        
[55] "Desert hedgehog"                "Potto"                         
[57] "Deer mouse"                     "Phalanger"                     
[59] "Caspian seal"                   "Common porpoise"               
[61] "Potoroo"                        "Giant armadillo"               
[63] "Rock hyrax"                     "Laboratory rat"                
[65] "African striped mouse"          "Squirrel monkey"               
[67] "Eastern american mole"          "Cotton rat"                    
[69] "Mole rat"                       "Arctic ground squirrel"        
[71] "Thirteen-lined ground squirrel" "Golden-mantled ground squirrel"
[73] "Musk shrew"                     "Pig"                           
[75] "Short-nosed echidna"            "Eastern american chipmunk"     
[77] "Brazilian tapir"                "Tenrec"                        
[79] "Tree shrew"                     "Bottle-nosed dolphin"          
[81] "Genet"                          "Arctic fox"                    
[83] "Red fox"                       

pull()

Use the tidyverse function pull() if you already have a sequence of piped-together functions and want to finish by extracting one single column and treating it as a vector.

You can pipe any dataframe into pull() and name the column you’d like to extract:

msleep |>
  pull(name)
 [1] "Cheetah"                        "Owl monkey"                    
 [3] "Mountain beaver"                "Greater short-tailed shrew"    
 [5] "Cow"                            "Three-toed sloth"              
 [7] "Northern fur seal"              "Vesper mouse"                  
 [9] "Dog"                            "Roe deer"                      
[11] "Goat"                           "Guinea pig"                    
[13] "Grivet"                         "Chinchilla"                    
[15] "Star-nosed mole"                "African giant pouched rat"     
[17] "Lesser short-tailed shrew"      "Long-nosed armadillo"          
[19] "Tree hyrax"                     "North American Opossum"        
[21] "Asian elephant"                 "Big brown bat"                 
[23] "Horse"                          "Donkey"                        
[25] "European hedgehog"              "Patas monkey"                  
[27] "Western american chipmunk"      "Domestic cat"                  
[29] "Galago"                         "Giraffe"                       
[31] "Pilot whale"                    "Gray seal"                     
[33] "Gray hyrax"                     "Human"                         
[35] "Mongoose lemur"                 "African elephant"              
[37] "Thick-tailed opposum"           "Macaque"                       
[39] "Mongolian gerbil"               "Golden hamster"                
[41] "Vole "                          "House mouse"                   
[43] "Little brown bat"               "Round-tailed muskrat"          
[45] "Slow loris"                     "Degu"                          
[47] "Northern grasshopper mouse"     "Rabbit"                        
[49] "Sheep"                          "Chimpanzee"                    
[51] "Tiger"                          "Jaguar"                        
[53] "Lion"                           "Baboon"                        
[55] "Desert hedgehog"                "Potto"                         
[57] "Deer mouse"                     "Phalanger"                     
[59] "Caspian seal"                   "Common porpoise"               
[61] "Potoroo"                        "Giant armadillo"               
[63] "Rock hyrax"                     "Laboratory rat"                
[65] "African striped mouse"          "Squirrel monkey"               
[67] "Eastern american mole"          "Cotton rat"                    
[69] "Mole rat"                       "Arctic ground squirrel"        
[71] "Thirteen-lined ground squirrel" "Golden-mantled ground squirrel"
[73] "Musk shrew"                     "Pig"                           
[75] "Short-nosed echidna"            "Eastern american chipmunk"     
[77] "Brazilian tapir"                "Tenrec"                        
[79] "Tree shrew"                     "Bottle-nosed dolphin"          
[81] "Genet"                          "Arctic fox"                    
[83] "Red fox"                       

select()

Use the tidyverse function select() if you want to select one or more columns and keep them in dataframe/tibble form.

For example, to select only name and genus from msleep:

msleep |>
  select(name, genus)
# A tibble: 83 × 2
   name                       genus      
   <chr>                      <chr>      
 1 Cheetah                    Acinonyx   
 2 Owl monkey                 Aotus      
 3 Mountain beaver            Aplodontia 
 4 Greater short-tailed shrew Blarina    
 5 Cow                        Bos        
 6 Three-toed sloth           Bradypus   
 7 Northern fur seal          Callorhinus
 8 Vesper mouse               Calomys    
 9 Dog                        Canis      
10 Roe deer                   Capreolus  
# ℹ 73 more rows

You can also use select() to remove specific columns! Between brackets, you write a minus sign - and then the name of the column to remove.

For example, let’s imagine we don’t care about the animals’ genus after all:

msleep |>
  select(-genus)
# A tibble: 83 × 10
   name         vore  order conservation sleep_total sleep_rem sleep_cycle awake
   <chr>        <chr> <chr> <chr>              <dbl>     <dbl>       <dbl> <dbl>
 1 Cheetah      carni Carn… lc                  12.1      NA        NA      11.9
 2 Owl monkey   omni  Prim… <NA>                17         1.8      NA       7  
 3 Mountain be… herbi Rode… nt                  14.4       2.4      NA       9.6
 4 Greater sho… omni  Sori… lc                  14.9       2.3       0.133   9.1
 5 Cow          herbi Arti… domesticated         4         0.7       0.667  20  
 6 Three-toed … herbi Pilo… <NA>                14.4       2.2       0.767   9.6
 7 Northern fu… carni Carn… vu                   8.7       1.4       0.383  15.3
 8 Vesper mouse <NA>  Rode… <NA>                 7        NA        NA      17  
 9 Dog          carni Carn… domesticated        10.1       2.9       0.333  13.9
10 Roe deer     herbi Arti… lc                   3        NA        NA      21  
# ℹ 73 more rows
# ℹ 2 more variables: brainwt <dbl>, bodywt <dbl>

The genus column is gone, we go straight from name to vore!

Square-bracket indexing

If you only want to extract a column with a specific index, you can do that by leaving the “row” part of the square bracket [row index, column index] notation blank.

You still need the comma though!! That’s how R knows whether it’s the column or the row that you’re after.

For example, to grab column 4:

msleep[, 4]
# A tibble: 83 × 1
   order       
   <chr>       
 1 Carnivora   
 2 Primates    
 3 Rodentia    
 4 Soricomorpha
 5 Artiodactyla
 6 Pilosa      
 7 Carnivora   
 8 Rodentia    
 9 Carnivora   
10 Artiodactyla
# ℹ 73 more rows

It looks weird, but it works!

Extract row(s)

slice()

The tidyverse function slice() fits well into a string of piped-together functions.

Imagine we want to keep rows 2 through 7:

msleep |>
  slice(2:7)
# A tibble: 6 × 11
  name    genus vore  order conservation sleep_total sleep_rem sleep_cycle awake
  <chr>   <chr> <chr> <chr> <chr>              <dbl>     <dbl>       <dbl> <dbl>
1 Owl mo… Aotus omni  Prim… <NA>                17         1.8      NA       7  
2 Mounta… Aplo… herbi Rode… nt                  14.4       2.4      NA       9.6
3 Greate… Blar… omni  Sori… lc                  14.9       2.3       0.133   9.1
4 Cow     Bos   herbi Arti… domesticated         4         0.7       0.667  20  
5 Three-… Brad… herbi Pilo… <NA>                14.4       2.2       0.767   9.6
6 Northe… Call… carni Carn… vu                   8.7       1.4       0.383  15.3
# ℹ 2 more variables: brainwt <dbl>, bodywt <dbl>

Square-bracket indexing

If you only want to extract a row with a specific index, you can do that by leaving the “column” part of the square bracket [row index, column index] notation blank.

You still need the comma though!! That’s how R knows whether it’s the column or the row that you’re after.

For example, to grab row 4:

msleep[4, ]
# A tibble: 1 × 11
  name    genus vore  order conservation sleep_total sleep_rem sleep_cycle awake
  <chr>   <chr> <chr> <chr> <chr>              <dbl>     <dbl>       <dbl> <dbl>
1 Greate… Blar… omni  Sori… lc                  14.9       2.3       0.133   9.1
# ℹ 2 more variables: brainwt <dbl>, bodywt <dbl>

Rows that meet a condition: filter()

Use the tidyverse function filter() if you want to keep only the rows that match some specific condition.

For example, to keep only the rows of msleep that contain carnivores, we want to filter msleep for the rows where the value of vore is "carni".

(An important note: we write this as vore == "carni", with two equals signs! Try it yourself with one equals sign and see what happens.)

msleep |>
  filter(vore == "carni")
# A tibble: 19 × 11
   name   genus vore  order conservation sleep_total sleep_rem sleep_cycle awake
   <chr>  <chr> <chr> <chr> <chr>              <dbl>     <dbl>       <dbl> <dbl>
 1 Cheet… Acin… carni Carn… lc                  12.1      NA        NA      11.9
 2 North… Call… carni Carn… vu                   8.7       1.4       0.383  15.3
 3 Dog    Canis carni Carn… domesticated        10.1       2.9       0.333  13.9
 4 Long-… Dasy… carni Cing… lc                  17.4       3.1       0.383   6.6
 5 Domes… Felis carni Carn… domesticated        12.5       3.2       0.417  11.5
 6 Pilot… Glob… carni Ceta… cd                   2.7       0.1      NA      21.4
 7 Gray … Hali… carni Carn… lc                   6.2       1.5      NA      17.8
 8 Thick… Lutr… carni Dide… lc                  19.4       6.6      NA       4.6
 9 Slow … Nyct… carni Prim… <NA>                11        NA        NA      13  
10 North… Onyc… carni Rode… lc                  14.5      NA        NA       9.5
11 Tiger  Pant… carni Carn… en                  15.8      NA        NA       8.2
12 Jaguar Pant… carni Carn… nt                  10.4      NA        NA      13.6
13 Lion   Pant… carni Carn… vu                  13.5      NA        NA      10.5
14 Caspi… Phoca carni Carn… vu                   3.5       0.4      NA      20.5
15 Commo… Phoc… carni Ceta… vu                   5.6      NA        NA      18.4
16 Bottl… Turs… carni Ceta… <NA>                 5.2      NA        NA      18.8
17 Genet  Gene… carni Carn… <NA>                 6.3       1.3      NA      17.7
18 Arcti… Vulp… carni Carn… <NA>                12.5      NA        NA      11.5
19 Red f… Vulp… carni Carn… <NA>                 9.8       2.4       0.35   14.2
# ℹ 2 more variables: brainwt <dbl>, bodywt <dbl>

There’s a LOT more you can do with filter()! Click here for some examples from the official documentation.