如何不使用dplyr去除含tibble列的data.table重复行
在不含dplyr的情况下为带tibble列的data.table去重
先重现你的场景:
library(data.table) library(tibble) # 构建含tibble列的data.table dt <- data.table( id = c(1, 1, 2), tbl_col = list(tibble(x = 1), tibble(x = 1), tibble(x = 2)) )
直接调用duplicated(dt)会触发报错,核心原因是data.table默认无法直接比较tibble这类复杂对象列的相等性。下面提供两种基于data.table原生语法的解决思路:
方法1:序列化tibble生成唯一标识
通过serialize将每个tibble转换为唯一的ASCII字符串,利用该字符串辅助判断重复:
# 不修改原表的写法 dt_unique <- dt[!duplicated( data.table( id, tbl_hash = vapply(tbl_col, function(x) rawToChar(serialize(x, NULL, ascii = TRUE)), character(1)) ) )] # 查看结果 dt_unique # id tbl_col # 1: 1 <tibble> # 2: 2 <tibble>
如果允许临时添加辅助列,也可以这么写:
dt[, tbl_hash := vapply(tbl_col, function(x) rawToChar(serialize(x, NULL, ascii = TRUE)), character(1))] dt_unique <- dt[!duplicated(list(id, tbl_hash)), .(id, tbl_col)] # 可选:删除辅助列 dt[, tbl_hash := NULL]
方法2:将tibble转为字符串表示
用dput把tibble转为可比较的字符串,原理和序列化类似:
dt_unique <- dt[!duplicated( data.table( id, tbl_str = vapply(tbl_col, dput, character(1)) ) )]
验证结果
两种方法得到的去重结果和dplyr::distinct(dt, .keep_all = TRUE)完全一致:
> dt_unique$tbl_col [[1]] # A tibble: 1 × 1 x <dbl> 1 1 [[2]] # A tibble: 1 × 1 x <dbl> 1 2
内容的提问来源于stack exchange,提问作者niciskl
相关产品推荐
相关产品推荐

