Cutting Through Data: A Practical Guide to dplyr::slice() in R

Social Capital Research Institute

Introduction

There’s a quiet moment in data analysis when everything feels too big—too many rows, too much noise. You don’t want everything. You want something precise.

That’s where slice() from dplyr comes in. It gives you direct control over rows by position.


Video Tutorial


Setup

library(dplyr)

df <- tibble(
  id = 1:10,
  name = c("A","B","C","D","E","F","G","H","I","J"),
  score = c(50, 60, 55, 70, 65, 80, 75, 90, 85, 95)
)

df
# A tibble: 10 × 3
      id name  score
   <int> <chr> <dbl>
 1     1 A        50
 2     2 B        60
 3     3 C        55
 4     4 D        70
 5     5 E        65
 6     6 F        80
 7     7 G        75
 8     8 H        90
 9     9 I        85
10    10 J        95

Basic Usage

# select first row
df %>% slice(1)
# A tibble: 1 × 3
     id name  score
  <int> <chr> <dbl>
1     1 A        50
# select specific rows
df %>% slice(2, 5, 7)
# A tibble: 3 × 3
     id name  score
  <int> <chr> <dbl>
1     2 B        60
2     5 E        65
3     7 G        75
# select a range
df %>% slice(1:3)
# A tibble: 3 × 3
     id name  score
  <int> <chr> <dbl>
1     1 A        50
2     2 B        60
3     3 C        55

Removing Rows

# remove first row
df %>% slice(-1)
# A tibble: 9 × 3
     id name  score
  <int> <chr> <dbl>
1     2 B        60
2     3 C        55
3     4 D        70
4     5 E        65
5     6 F        80
6     7 G        75
7     8 H        90
8     9 I        85
9    10 J        95
# remove first three rows
df %>% slice(-(1:3))
# A tibble: 7 × 3
     id name  score
  <int> <chr> <dbl>
1     4 D        70
2     5 E        65
3     6 F        80
4     7 G        75
5     8 H        90
6     9 I        85
7    10 J        95

Grouped Data

df %>%
  mutate(group = ifelse(id <= 5, "A", "B")) %>%
  group_by(group) %>%
  slice(1)
# A tibble: 2 × 4
# Groups:   group [2]
     id name  score group
  <int> <chr> <dbl> <chr>
1     1 A        50 A    
2     6 F        80 B    

Helper Functions

# first n rows
df %>% slice_head(n = 3)
# A tibble: 3 × 3
     id name  score
  <int> <chr> <dbl>
1     1 A        50
2     2 B        60
3     3 C        55
# last n rows
df %>% slice_tail(n = 3)
# A tibble: 3 × 3
     id name  score
  <int> <chr> <dbl>
1     8 H        90
2     9 I        85
3    10 J        95
# highest values
df %>% slice_max(order_by = score, n = 3)
# A tibble: 3 × 3
     id name  score
  <int> <chr> <dbl>
1    10 J        95
2     8 H        90
3     9 I        85
# lowest values
df %>% slice_min(order_by = score, n = 3)
# A tibble: 3 × 3
     id name  score
  <int> <chr> <dbl>
1     1 A        50
2     3 C        55
3     2 B        60
# random sample
df %>% slice_sample(n = 3)
# A tibble: 3 × 3
     id name  score
  <int> <chr> <dbl>
1     2 B        60
2     6 F        80
3     8 H        90

Real Use Case

df %>%
  mutate(group = ifelse(id <= 5, "A", "B")) %>%
  group_by(group) %>%
  slice_max(order_by = score, n = 2)
# A tibble: 4 × 4
# Groups:   group [2]
     id name  score group
  <int> <chr> <dbl> <chr>
1     4 D        70 A    
2     5 E        65 A    
3    10 J        95 B    
4     8 H        90 B    

Key Takeaway

That difference is small—but powerful.


Closing

slice() is simple, but once you start using it, it becomes one of those tools you reach for constantly. It gives you control over the structure of your data without overcomplicating things.