在R语言中获取重复Tag对应的最新SEnd记录方法问询
问题:按Tag获取最新SEnd的唯一记录
我有如下数据集,目标是为每个独立的Tag获取对应的最新SEnd值,最终保留Tag、Owner及最新SEnd等相关字段(本质是获取SEnd的最新年份)。我尝试了下面的dplyr代码,想问问有没有合适的函数来排序、剔除冗余条目,保留每个Tag对应的唯一最新SEnd记录:
latest_dates <- merged_df %>% group_by(Tag) %>% arrange(desc(merged_df$`SEnd`)) %>% top_n(1) %>% select(`SEnd`)
原始数据集
| Tag | Date | Time | Name | SEnd | Owner |
|---|---|---|---|---|---|
| 10GS3 | 06/14/2015 | 01:00:00 am | LATITUDE E7250 | 2018 | Show |
| 10GS3 | 06/14/2015 | 01:00:00 am | LATITUDE E7250 | 2018 | Chris |
| 10GS3 | 06/14/2015 | 01:00:00 am | LATITUDE E7250 | 2020 | Show |
| 10GS3 | 06/14/2015 | 01:00:00 am | LATITUDE E7250 | 2020 | Chris |
| 12267 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2021 | Patrick O C |
| 12268 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2021 | None |
| 12267 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2021 | Patrcik O C |
| 12267 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2021 | Patrick O C |
| 12268 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2021 | None |
| 12267 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2021 | Patrcik O C |
| 12267 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2021 | Patrick O C |
| 12268 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2021 | None |
| 12267 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2021 | Patrcik O C |
| 12267 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2025 | Patrick O C |
| 12268 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2025 | None |
期望输出
| Tag | Date | Time | Name | SEnd | Owner |
|---|---|---|---|---|---|
| 10GS3 | 06/14/2015 | 01:00:00 am | LATITUDE E7250 | 2020 | Chris |
| 12267 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2025 | Patrick O C |
| 12268 | 09/24/2020 | 12:00:00 am | LATITUDE 5410 | 2025 | None |
解决方案
先指出你原代码的几个问题:
- 分组后
arrange里不需要用merged_df$引用列,直接写desc(SEnd)即可,否则会忽略分组上下文 top_n(1)在同一组存在多条相同最大SEnd的记录时,会保留所有符合条目,无法保证每个Tag只留一条select(SEnd)只保留了SEnd列,没满足你保留多字段的需求
下面是几种符合需求的实现方式:
方法1:使用slice_max(推荐)
dplyr 1.0.0及以上版本提供的slice_max可以直接按分组取最大的n条记录,设置with_ties = FALSE就能确保每个组只留一条:
latest_records <- merged_df %>% group_by(Tag) %>% slice_max(order_by = SEnd, n = 1, with_ties = FALSE) %>% ungroup() # 取消分组,根据需求可选
方法2:排序后取每组第一条
先按Tag分组,再按SEnd降序排序,然后提取每组的第一条记录:
latest_records <- merged_df %>% group_by(Tag) %>% arrange(desc(SEnd), .by_group = TRUE) %>% # .by_group=TRUE确保在分组内排序 slice(1) %>% ungroup()
方法3:筛选最大SEnd后去重
先找出每个Tag的最大SEnd值,再筛选出对应记录,最后按Tag去重保留第一条:
latest_records <- merged_df %>% group_by(Tag) %>% filter(SEnd == max(SEnd)) %>% distinct(Tag, .keep_all = TRUE) %>% ungroup()
以上三种方法都能得到你想要的期望输出。如果同一Tag同一最大SEnd有多条记录(比如10GS3的2020年有两条),这些方法都会保留排序后的第一条,和你的期望输出一致。
内容的提问来源于stack exchange,提问作者pat
相关产品推荐
相关产品推荐

