You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按分组提取每组最后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()

步骤解释

  1. 分组:group_by(id)确保后续操作按每个id单独处理。
  2. 标记目标值位置:两种方法分别通过逆序行号或截取后反转行号,标记出最后4个值对应的列名(last/last2等)。
  3. 筛选目标行:保留每组内最后4个值的记录。
  4. 转宽表:pivot_wider将长格式的分组数据转为宽格式,自动为不足4个值的组填充NA。
  5. 取消分组:ungroup()还原数据框的非分组状态。

内容的提问来源于stack exchange,提问作者Ai4l2s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 21:32:15