dplyr::slice()

slice(.data, ...)
Returns: tibble · Updated March 13, 2026 · Tidyverse
dplyr slice data-manipulation tidyverse

The dplyr slice functions provide flexible ways to select rows from a data frame or tibble based on position, random sampling, or rank. While slice() selects rows by integer positions, slice_head() and slice_tail() take the first or last rows, slice_sample() randomly samples rows, and slice_min()/slice_max() select rows with extreme values in a specified column.

These functions are designed for readability and integration with the tidyverse pipeline (%>%). They are particularly useful for data exploration, creating training/test splits, and extracting top/bottom records.

Syntax

slice(.data, ...)
slice_head(.data, n, prop)
slice_tail(.data, n, prop)
slice_sample(.data, n, prop, replace = FALSE, weight_by = NULL)
slice_min(.data, order_by, n, prop, with_ties = TRUE)
slice_max(.data, order_by, n, prop, with_ties = TRUE)

Parameters

ParameterTypeDefaultDescription
.datatibble / data.frameRequiredThe tibble or data frame to slice
...integerRequired (for slice())Row positions to select (positive integers select rows, negative integers drop rows)
nintegerOptional (for slice_head/tail/sample/min/max)Number of rows to select. Either n or prop must be supplied
propnumericOptionalProportion of rows to select (0 < prop ≤ 1). Either n or prop must be supplied
replacelogicalFALSE (for slice_sample)Sample with replacement?
weight_bynumeric vectorNULL (for slice_sample)Sampling weights; must be same length as number of rows
order_byunquoted column nameRequired (for slice_min/max)Column to rank rows by
with_tieslogicalTRUE (for slice_min/max)Keep ties? If TRUE, all rows with the same extreme value are returned

Examples

Basic slice() usage

library(dplyr)

df <- tibble(
  id = 1:10,
  value = rnorm(10)
)

# Select rows 1, 3, 5
df %>% slice(1, 3, 5)

# Select first 5 rows (equivalent to head)
df %>% slice(1:5)

# Drop rows 2 and 4 (negative indexing)
df %>% slice(-2, -4)

slice_head() and slice_tail()

# First 3 rows
df %>% slice_head(n = 3)

# Last 20% of rows
df %>% slice_tail(prop = 0.2)

# slice_tail with negative n (drops last rows)
df %>% slice_tail(n = -5)  # drops last 5 rows, returns first (nrow - 5) rows

Random sampling with slice_sample()

# Randomly select 5 rows without replacement
df %>% slice_sample(n = 5)

# Randomly select 10% of rows with replacement
df %>% slice_sample(prop = 0.1, replace = TRUE)

# Weighted sampling (e.g., probability proportional to value)
df %>% slice_sample(n = 2, weight_by = abs(value))

Selecting extreme values with slice_min() and slice_max()

# 3 rows with smallest 'value'
df %>% slice_min(value, n = 3)

# Top 20% of rows by 'value'
df %>% slice_max(value, prop = 0.2)

# When ties exist, with_ties controls whether all ties are kept
df %>% slice_min(value, n = 1, with_ties = FALSE)  # returns exactly 1 row

Common Patterns

Creating training/test splits

set.seed(123)
train <- df %>% slice_sample(prop = 0.7)
test  <- df %>% slice_sample(prop = 0.3)

Removing the first/last rows after grouping

df %>%
  group_by(category) %>%
  slice(-1)  # drop first row of each group

Selecting top N per group

df %>%
  group_by(category) %>%
  slice_max(value, n = 3)  # top 3 rows per group

Random permutation of rows

df %>% slice_sample(prop = 1)  # reshuffle all rows (no replacement)

Sampling with stratification

df %>%
  group_by(stratum) %>%
  slice_sample(n = 5)  # sample 5 rows from each stratum

Performance Notes

  • slice() is very fast; it uses integer indexing.
  • slice_sample() with replacement can be slower on large datasets.
  • For grouped operations, each group is sliced independently, which can be memory-intensive with many groups.
  • When using slice_min()/slice_max() on unsorted data, dplyr performs a partial sort; consider pre-sorting if performance is critical.

See Also