使用dplyr提取tibble数据链中最新更新的行记录
用dplyr保留每条数据链的最新记录
问题背景
original_tibble包含3条数据链,演化规则为:
- 链首记录的
parentId与id相等,origId为NA并带有value值;- 每次更新value时,新增行的
parentId为链内最新记录的id,origId为链首的id,id为唯一标识,value为新值。数据链行序不固定,无法依赖排序。需要保留每条数据链的最新行并移除历史条目,最终得到
final_tibble的结果,优先使用dplyr实现。
原始数据代码
library(dplyr) my_tibble <- tibble( parentId = character(), origId = character(), id = character(), value = double() ) original_tibble <- my_tibble %>% add_row(parentId = "2024Z123", origId = NA, id = "2024Z123", value = 2) %>% add_row(parentId = "2024Z123", origId = "2024Z123", id = "2024A652", value = 6) %>% add_row(parentId = "2024A652", origId = "2024Z123", id = "2024X156", value = 5) %>% add_row(parentId = "2020G001", origId = NA, id = "2020G001", value = 1) %>% add_row(parentId = "2020G001", origId = "2020G001", id = "2024Z156", value = 2) %>% add_row(parentId = "2021B456", origId = NA, id = "2021B456", value = 3) final_tibble <- my_tibble %>% add_row(parentId = "2024A652", origId = "2024Z123", id = "2024X156", value = 5) %>% add_row(parentId = "2020G001", origId = "2020G001", id = "2024Z156", value = 2) %>% add_row(parentId = "2021B456", origId = NA, id = "2021B456", value = 3)
解决方案
实现思路
每条数据链的核心标识是链首的id(链首记录的origId为NA,后续记录的origId均等于该链首id)。要找到最新记录,只需判断:这条记录的id没有被其他记录作为parentId使用——因为最新记录不会成为任何后续更新的父节点。
dplyr代码实现
library(dplyr) # 处理逻辑 result_tibble <- original_tibble %>% # 标记每条记录所属的链首id mutate(chain_root = coalesce(origId, id)) %>% # 筛选出id未被作为其他记录parentId的行(即最新记录) filter(!id %in% original_tibble$parentId) %>% # 移除临时辅助列 select(-chain_root) # 验证结果是否与final_tibble一致 all.equal(result_tibble, final_tibble) #> [1] TRUE
代码说明
coalesce(origId, id):自动取origId的值(非NA时),否则用自身id,确保同链记录拥有统一的链首标识。!id %in% original_tibble$parentId:筛选出从未被作为父节点的记录,这些就是每条链的最后(最新)条目。
内容的提问来源于stack exchange,提问作者AColoredReptile
相关产品推荐
相关产品推荐

