How to get the last value of each group in R
library(dplyr)
When analyzing grouped data in R, a common requirement is to retrieve the last value within each group. This task frequently arises in business reporting, time-series analysis, customer analytics, financial modeling, and sales dashboards where you need the most recent observation for each category.
Fortunately, R provides several efficient ways to extract the last value from each group using functions from base R, dplyr, and data.table.
In this tutorial, you’ll learn:
- How to get the last value of each group in R
- Using
aggregate() - Using
dplyr::group_by() - Using
slice_tail() - Using
data.table - How to get the last row of each group
- Best practices for grouped data analysis
Sample Dataset
Let’s create a sample data frame containing sales information by state.
df1 <- data.frame(
Name = c('A','B','C','D','E','F','G','H','I','J','K','L'),
State = c('S1','S1','S2','S2','S3','S3','S3','S4','S4','S4','S4','S4'),
Sales = c(124,224,231,212,123,71,39,131,188,186,198,134)
)
df1Output:
| Name | State | Sales |
|---|---|---|
| A | S1 | 124 |
| B | S1 | 224 |
| C | S2 | 231 |
| D | S2 | 212 |
| E | S3 | 123 |
| F | S3 | 71 |
| G | S3 | 39 |
| H | S4 | 131 |
| I | S4 | 188 |
| J | S4 | 186 |
| K | S4 | 198 |
| L | S4 | 134 |
Our objective is to obtain the last Sales value for each State.
Method 1: Using aggregate()
The aggregate() function from base R can summarize values by group.
aggregate(
Sales ~ State,
data = df1,
FUN = dplyr::last
)Output:
| State | Sales |
|---|---|
| S1 | 224 |
| S2 | 212 |
| S3 | 39 |
| S4 | 134 |
Explanation
The last() function returns the final observation within each state group.
For example:
- S1 → 224
- S2 → 212
- S3 → 39
- S4 → 134
Method 2: Using dplyr group_by() and summarise()
The dplyr package provides a clean and readable approach.
library(dplyr)
df1 %>%
group_by(State) %>%
summarise(
Last_Value = last(Sales)
)Output:
# A tibble: 4 × 2
State Last_Value
<chr> <dbl>
1 S1 224
2 S2 212
3 S3 39
4 S4 134Why Use dplyr?
Benefits include:
- Easy to read
- Fast on large datasets
- Integrates with tidyverse workflows
- Supports multiple summary statistics
Method 3: Using slice_tail() to Get the Last Row of Each Group
Sometimes you need the entire last record rather than just one column.
library(dplyr)
df1 %>%
group_by(State) %>%
slice_tail(n = 1)Output:
| Name | State | Sales |
|---|---|---|
| B | S1 | 224 |
| D | S2 | 212 |
| G | S3 | 39 |
| L | S4 | 134 |
This returns the complete last row for each group.
Method 4: Using data.table
For large datasets, data.table is one of the fastest solutions.
library(data.table)
dt <- as.data.table(df1)
dt[, .(Last_Value = last(Sales)), by = State]Output:
| State | Last_Value |
|---|---|
| S1 | 224 |
| S2 | 212 |
| S3 | 39 |
| S4 | 134 |
Getting the Last Value After Sorting
In real-world datasets, the “last” value often refers to the most recent observation based on a date or timestamp.
Consider the following dataset:
df2 <- data.frame(
State = c("S1","S1","S1","S2","S2"),
Date = as.Date(c(
"2025-01-01",
"2025-03-01",
"2025-05-01",
"2025-02-01",
"2025-04-01"
)),
Sales = c(100,150,220,180,250)
)Retrieve the latest sales value by date:
df2 %>%
arrange(State, Date) %>%
group_by(State) %>%
summarise(
Latest_Sales = last(Sales)
)Output:
| State | Latest_Sales |
|---|---|
| S1 | 220 |
| S2 | 250 |
Get the Last Value for Multiple Columns
You can summarize multiple variables simultaneously.
df1 %>%
group_by(State) %>%
summarise(
Last_Sales = last(Sales),
Last_Name = last(Name)
)Output:
| State | Last_Sales | Last_Name |
|---|---|---|
| S1 | 224 | B |
| S2 | 212 | D |
| S3 | 39 | G |
| S4 | 134 | L |
Common Use Cases
Retrieving the last value of each group is useful for:
Sales Analytics
Find the latest sales transaction by region.
Customer Analytics
Retrieve the most recent customer activity.
Financial Analysis
Get the latest stock price by company.
Inventory Management
Track the most recent stock level for each warehouse.
Time-Series Reporting
Extract the latest observation for each category.
Common Mistakes
Not Sorting Data First
Consider:
df %>%
group_by(State) %>%
summarise(last(Sales))If records are not ordered correctly, the result may not represent the most recent observation.
Always sort when dealing with dates:
arrange(Date)before applying last().
Missing Values
If the last value is missing:
c(100, 150, NA)then:
last(c(100,150,NA))returns:
NATo get the last non-missing value:
last(na.omit(c(100,150,NA)))Output:
150Best Practices
- Sort data before extracting the last observation.
- Use
slice_tail()when you need complete rows. - Use
summarise(last())for quick aggregations. - Use
data.tablefor very large datasets. - Handle missing values appropriately.
Conclusion
Getting the last value of each group in R is straightforward using either base R or modern packages such as dplyr and data.table.
The most commonly used solution is:
library(dplyr)
df1 %>%
group_by(State) %>%
summarise(
Last_Value = last(Sales)
)This approach is simple, readable, and efficient for most data analysis workflows.
Whether you’re working with sales data, customer transactions, financial records, or time-series datasets, extracting the most recent value per group is a valuable technique that every R user should know.

