如何按分组提取每组最后4个值并重塑R语言tibble数据?
提取分组后最后4个值并重塑为宽表
问题背景
现有如下数据框:
df <- tibble(id = c(1, 1, 1, 2, 2, 2, 2), value = c(1, 2, 3, 1, 5, 4, 1))
需要按id分组,保留每组最后出现的4个value,并重塑为宽表,期望输出:
# A tibble: 2 × 5 id last last2 last3 last4 <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 3 2 1 NA 2 2 1 4 5 1
完整解决方案
可以结合dplyr的分组、行号标记,以及tidyr的宽表转换来实现,以下是两种可行方法:
方法一:通过逆序行号筛选
library(dplyr) library(tidyr) df %>% group_by(id) %>% # 给组内行按逆序编号(最后一行=1,倒数第二=2...) mutate(row_num = row_number(desc(row_number()))) %>% # 保留最后4个值 filter(row_num <= 4) %>% # 生成目标列名 mutate(col_name = paste0("last", ifelse(row_num == 1, "", row_num))) %>% # 转宽表,缺失值填充NA pivot_wider(names_from = col_name, values_from = value, values_fill = NA) %>% ungroup()
方法二:直接截取最后4行再反转编号
df %>% group_by(id) %>% # 直接截取每组最后4行 slice_tail(n = 4) %>% # 反转行号,让最后一行对应last,倒数第二对应last2... mutate(col_name = paste0("last", rev(row_number()))) %>% pivot_wider(names_from = col_name, values_from = value, values_fill = NA) %>% ungroup()
步骤解释
- 分组:
group_by(id)确保后续操作按每个id单独处理。 - 标记目标值位置:两种方法分别通过逆序行号或截取后反转行号,标记出最后4个值对应的列名(
last/last2等)。 - 筛选目标行:保留每组内最后4个值的记录。
- 转宽表:
pivot_wider将长格式的分组数据转为宽格式,自动为不足4个值的组填充NA。 - 取消分组:
ungroup()还原数据框的非分组状态。
内容的提问来源于stack exchange,提问作者Ai4l2s
相关产品推荐
相关产品推荐

