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

如何在dplyr管道语句中保留每组最完整信息的行?

问题描述

输入数据集的每个ID组内存在冗余的info信息:部分行包含带_detail后缀的完整信息,部分行只有基础信息;还有部分ID组从未出现过完整信息。需要按ID和信息类型保留每组中最完整的行,且全程使用单个dplyr管道完成,无需中间变量。

输入示例

df <- data.frame(ID = c(1, 1, 1, 2, 3, 3, 3, 3),
                 info = c("info1#info1_detail", "info1", "info3",
                          "info1",
                          "info1#info1_detail", "info1",
                          "info2#info2_detail", "info2"))

# 输出结果:
#   ID               info
# 1  1 info1#info1_detail
# 2  1              info1
# 3  1              info3
# 4  2              info1
# 5  3 info1#info1_detail
# 6  3              info1
# 7  3 info2#info2_detail
# 8  3              info2

期望输出示例

result <- data.frame(ID = c(1, 1, 2, 3, 3),
                     info = c("info1#info1_detail",
                              "info3",
                              "info1",
                              "info1#info1_detail",
                              "info2#info2_detail"))

# 输出结果:
#   ID               info
# 1  1 info1#info1_detail
# 2  1              info3
# 3  2              info1
# 4  3 info1#info1_detail
# 5  3 info2#info2_detail
解决方案

使用dplyr结合stringr的管道操作即可实现需求,代码如下:

library(dplyr)
library(stringr)

df %>%
  # 提取info的基础部分(去除#及后续的_detail内容)
  mutate(base_info = str_remove(info, "#.*")) %>%
  # 按ID和基础信息分组,确保同一ID下的同类型信息归为一组
  group_by(ID, base_info) %>%
  # 筛选每组中info字符长度最长的行(优先保留带_detail的完整信息)
  slice_max(nchar(info), n = 1) %>%
  # 取消分组
  ungroup() %>%
  # 移除临时生成的base_info列
  select(-base_info)

逻辑说明

  1. 生成基础信息列:通过str_remove提取info字段中#之前的内容,作为同类型信息的分组依据;
  2. 分组筛选:按ID和base_info分组后,用slice_max选择每组中字符长度最长的行——带_detail的信息长度更长,会被优先保留;如果某组只有基础信息,则直接保留该行;
  3. 清理结果:取消分组并移除临时的base_info列,得到最终的去重后保留完整信息的数据集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 09:10:21