tidyr chop() in R: Group Rows Into List Columns
The chop() function in tidyr collapses rows within groups into list-column cells. Each cell holds a vector of the values from rows in that group. It is a lighter-weight version of nest().
df |> chop(c(value)) # vector list-col, one per group row df |> chop(c(value, score)) # multiple list cols df |> unchop(value) # opposite df |> nest(.by = group) # different: tibble list col
Need explanation? Read on for examples and pitfalls.
What chop() does in one sentence
chop(data, cols) collapses each group's rows in cols into a list-column where each cell is a vector of the original values. Lighter than nest, which creates a tibble per cell.
Syntax
chop(data, cols, ..., error_call = caller_env()). cols are the columns to collapse.
Five common patterns
1. Standard chop
Group columns are detected automatically (the unchosen ones).
2. Multiple chopped columns
3. Compute on chopped lists
4. Round-trip with unchop
5. Compare with nest
chop is to nest as vectors are to data frames. chop creates list-of-vector cells; nest creates list-of-tibble cells. For single-column collapsing, chop is more efficient.chop() vs nest() vs summarise(list(...))
| Function | Cell type | Best for |
|---|---|---|
chop(col) |
Vector | Single-column collapse |
nest(.by = g) |
Tibble | Multi-column collapse |
summarise(x = list(col)) |
Vector (manual) | Inside summarise pipelines |
A practical workflow
Use chop for "list of values per group" patterns.
Per group: list of timestamps, plus first and last.
Common pitfalls
Pitfall 1: forgetting cols argument. chop(df) with no cols just returns df. You must specify which columns to collapse.
Pitfall 2: confusing with nest. chop = vectors; nest = tibbles. Different cell types.
chop() collapses by ALL non-chopped columns implicitly. All other columns must be unique per group, or chop creates surprising groupings.Try it yourself
Try it: Chop the value column per group, count items per group. Save to ex_chopped.
Click to reveal solution
Explanation: chop(v) collapses values per g; map_int(v, length) counts items.
Related tidyr functions
After mastering chop, look at:
unchop(): opposite (vectors to rows)nest(): tibble versionunnest(): tibble version of unchopsummarise(list(...)): alternative for collapse
FAQ
What does chop do in tidyr?
chop(data, cols) collapses each group's rows in cols into a list-column where each cell is a vector. Lighter than nest.
What is the difference between chop and nest?
chop creates VECTOR list cells. nest creates TIBBLE list cells. chop for single-column collapse; nest for multi-column.
Is chop faster than nest?
Slightly, for single-column cases. The difference is small but chop avoids the tibble wrapping.
How do I expand chopped columns?
unchop(col) is the inverse. Returns the original row-per-row form.
When should I use chop vs nest?
chop for one or a few related columns into vectors. nest for collapsing all non-grouping columns into a tibble.