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

使用data.table的duplicated函数去重未达预期,请教问题原因

data.table多列去重失败的原因分析

问题场景

先看第一个data.table对象df:

df <- data.table(id = c(1, 2, 2, 3)
                , datee = as.Date(c('2022-01-01', '2022-01-02', '2022-01-02', '2022-01-03'))
                ); df

输出:

id      datee
1:  1 2022-01-01
2:  2 2022-01-02
3:  2 2022-01-02
4:  3 2022-01-03

使用df[!duplicated(id, datee)]得到了预期的去重结果:

df[!duplicated(id, datee)]

输出:

id      datee
1:  1 2022-01-01
2:  2 2022-01-02
3:  3 2022-01-03

但对第二个data.table对象df_1:

df_1 <- data.table(a = c(1,1,2)
                 , b = c(1,1,3)
                 ); df_1

输出:

a b
1: 1 1
2: 1 1
3: 2 3

用同样的写法df_1[!duplicated(a, b)]却无法去除重复行,结果还是原表:

df_1[!duplicated(a, b)]

输出:

a b
1: 1 1
2: 1 1
3: 2 3

错误原因

你误用了base R的duplicated()函数参数逻辑:

  • base R的duplicated(x, ...)中,第一个参数x是要检查重复的对象(可以是向量、数据框),第二个参数fromLast是布尔值,控制从后往前检查重复。
  • 你写的duplicated(id, datee)实际上是把id向量作为x,datee被强制转换成布尔值(非零日期都为TRUE),作为fromLast参数传入,本质是仅对id列做从后往前的重复检查,而非基于id和datee两列去重。
  • 第一个例子看似成功,只是巧合:你的数据中id重复的行刚好datee也重复,仅基于id去重就得到了符合预期的结果,但这并非同时用两列去重的逻辑。

正确的多列去重方法

针对data.table的多列去重,推荐以下几种写法:

  1. 使用data.table专属的unique()函数,指定去重依据列:
unique(df_1, by = c("a", "b"))

输出:

a b
1: 1 1
2: 2 3
  1. 在duplicated()中传入指定列组成的对象,再取反:
# 方法2.1:传入列组成的data.table
df_1[!duplicated(df_1[, .(a, b)])]

# 方法2.2:直接指定by参数(data.table兼容该参数)
df_1[!duplicated(df_1, by = c("a", "b"))]
  1. 使用.SD指代当前分组的所有列,配合by参数:
df_1[!duplicated(.SD, by = c("a", "b"))]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:40:31