如何在R中使用data.table删除所有重复行

5

假设我们有

library(data.table)    
dt <- data.table(Date = c(201405,201405,201504,201505, 201505,201505), ID = c(500,500,600,700,500, 700), INC = c(20,30,50,75,80,90))

返回,

     Date  ID INC
1: 201405 500  20
2: 201405 500  30
3: 201504 600  50
4: 201505 700  75
5: 201505 500  80
6: 201505 700  90

我希望移除所有在同一日期的ID。返回结果应该如下所示:
     Date  ID INC
1: 201504 600  50
2: 201505 500  80

您能否提供建议?

1个回答

7
我们按照 'ID' 进行分组,在 'Date' 上使用 duplicated 获取逻辑索引并取反,这样所有独特的元素都将是 TRUE。使用 .I 获取行索引,提取索引列 'V1' 并用它来对 'dt' 进行子集筛选。
dt[dt[, .I[!(duplicated(Date)|duplicated(Date, fromLast=TRUE))], ID]$V1]
#      Date  ID INC
#1: 201505 500  80
#2: 201504 600  50

另一个选择是按“日期”、“ID”分组,如果nrow等于1(.N==1),我们获取Data.table的子集(.SD)。

dt[, if(.N==1) .SD, .(Date, ID)]
#     Date  ID INC
#1: 201504 600  50
#2: 201505 500  80

正如@Frank所提到的,我们可以使用data.table/base R组合

DT[ave(seq(.N), Date, ID, FUN = function(x) length(x) == 1L)]

1
我在 dt[dt[, !(duplicated(ID)|duplicated(ID,fromLast=TRUE)), by=Date]$V1] 中有一个类似的。 - thelatemail
@thelatemail 那看起来也没问题。我通常会选择.I - akrun
1
我会考虑使用DT[ave(seq(.N), Date, ID, FUN = function(x) length(x) == 1L)]。虽然不太符合data.table的风格,但它不需要使用by或两次扫描向量来查找重复项。 - Frank
1
@Frank - 其实 ave 函数在内部调用了 lapplysplit,因此它确实使用了 by - thelatemail
基于毫无依据的猜测,我怀疑使用 by 拆分数据框的开销比拆分单个向量要大...哦——刚刚测试了一下是否能够制作一个例子,在半秒钟内进行了 if (...) .SD 后,我的 R 会话在执行 ave 时挂起了,所以...没错。 - Frank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接