Vas*_*y A 29 r data.table
如果我理解正确,duplicated()函数data.table返回一个逻辑向量,它不包含第一次出现的重复记录.标记第一次出现的最佳方法是什么?在这种情况下base::duplicated(),我只是通过与逆序函数分离来解决这个问题:myDups <- (duplicated(x) | duplicated(x, fromLast=TRUE))- 但是data.table::duplicated(),fromLast=TRUE不包括在内(我不知道为什么)......
PS好的,这是一个原始的例子
myDT <- fread(
"id,fB,fC
1, b1,c1
2, b2,c2
3, b1,c1
4, b3,c3
5, b1,c1
")
setkeyv(myDT, c('fB', 'fC'))
myDT[, fD:=duplicated(myDT)]
Run Code Online (Sandbox Code Playgroud)
第1,3和5行都是重复的,但只有3和5将被包括在内,duplicated而我需要标记所有这些.
UPD.重要提示:我在下面接受的答案仅适用于键控表.如果要查找考虑所有列的重复记录,则必须setkey明确显示所有这些列.到目前为止,我专门针对这种情况使用以下解决方法:
dups1 <- duplicated(myDT);
dups2 <- duplicated(myDT, fromLast=T);
dups <- dups1 | dups2;
Run Code Online (Sandbox Code Playgroud)
edd*_*ddi 14
许多年前,这是最快的答案(如果感兴趣,请参阅修订历史):
dups = duplicated(myDT, by = key(myDT));
myDT[, fD := dups | c(tail(dups, -1), FALSE)]
Run Code Online (Sandbox Code Playgroud)
从那时起,已经有很多内部变化,但是对于相同的顺序做了很多选择:
myDT <- data.table(id = sample(1e6),
fB = sample(seq_len(1e3), size= 1e6, replace=TRUE),
fC = sample(seq_len(1e3), size= 1e6,replace=TRUE ))
setkey(myDT, fB, fC)
microbenchmark(
key=myDT[, fD := .N > 1, by = key(myDT)],
unique=myDT[unique(myDT, by = key(myDT)),fD:=.N>1],
dup = myDT[,fD := duplicated.data.frame(.SD)|duplicated.data.frame(.SD, fromLast=TRUE),
.SDcols = key(myDT)],
dup2 = {dups = duplicated(myDT, by = key(myDT)); myDT[, fD := dups | c(tail(dups, -1L), FALSE)]},
dup3 = {dups = duplicated(myDT, by = key(myDT)); myDT[, fD := dups | c(dups[-1L], FALSE)]},
times=10)
# expr min lq mean median uq max neval
# key 523.3568 567.5372 632.2379 578.1474 678.4399 886.8199 10
# unique 189.7692 196.0417 215.4985 210.5258 224.4306 290.2597 10
# dup 4440.8395 4685.1862 4786.6176 4752.8271 4900.4952 5148.3648 10
# dup2 143.2756 153.3738 236.4034 161.2133 318.1504 419.4082 10
# dup3 144.1497 150.9244 193.3058 166.9541 178.0061 460.5448 10
Run Code Online (Sandbox Code Playgroud)
mri*_*rip 13
这似乎有效:
> myDT[unique(myDT),fD:=.N>1]
> myDT
id fB fC fD
1: 1 b1 c1 TRUE
2: 3 b1 c1 TRUE
3: 5 b1 c1 TRUE
4: 2 b2 c2 FALSE
5: 4 b3 c3 FALSE
Run Code Online (Sandbox Code Playgroud)
感谢@flodel,更好的方法是:
> myDT[, fD := .N > 1, by = key(myDT)]
> myDT
id fB fC fD
1: 1 b1 c1 TRUE
2: 3 b1 c1 TRUE
3: 5 b1 c1 TRUE
4: 2 b2 c2 FALSE
5: 4 b3 c3 FALSE
Run Code Online (Sandbox Code Playgroud)
效率差异很大:
> microbenchmark(
key=myDT[, fD := .N > 1, by = key(myDT)],
unique=myDT[unique(myDT),fD:=.N>1])
Unit: microseconds
expr min lq median uq max neval
key 679.874 715.700 735.0575 773.7595 1825.437 100
unique 1417.845 1485.913 1522.7475 1567.9065 24053.645 100
Run Code Online (Sandbox Code Playgroud)
特别是对于最大.那里发生了什么?
第三种方法(对于这个小例子看来效率更高)
你可以明确地打电话duplicated.data.frame....
myDT[,fD := duplicated.data.frame(.SD)|duplicated.data.frame(.SD, fromLast=TRUE),
.SDcols = key(myDT)]
microbenchmark(
key=myDT[, fD := .N > 1, by = key(myDT)],
unique=myDT[unique(myDT),fD:=.N>1],
dup = myDT[,fD := duplicated.data.frame(.SD)|duplicated.data.frame(.SD, fromLast=TRUE),
.SDcols = key(myDT)])
## Unit: microseconds
## expr min lq median uq max neval
## key 556.608 575.9265 588.906 600.9795 27713.242 100
## unique 1112.913 1164.8310 1183.244 1216.9000 2263.557 100
## dup 420.173 436.3220 448.396 461.3750 699.986 100
Run Code Online (Sandbox Code Playgroud)
如果我们扩大样本的大小data.table,那么该key方法是明显的赢家
myDT <- data.table(id = sample(1e6),
fB = sample(seq_len(1e3), size= 1e6, replace=TRUE),
fC = sample(seq_len(1e3), size= 1e6,replace=TRUE ))
setkeyv(myDT, c('fB', 'fC'))
microbenchmark(
key=myDT[, fD := .N > 1, by = key(myDT)],
unique=myDT[unique(myDT),fD:=.N>1],
dup = myDT[,fD := duplicated.data.frame(.SD)|duplicated.data.frame(.SD, fromLast=TRUE),
.SDcols = key(myDT)],times=10)
## Unit: milliseconds
## expr min lq median uq max neval
## key 355.9258 358.1764 360.7628 450.9218 500.8360 10
## unique 451.3794 458.0258 483.3655 519.3341 553.2515 10
## dup 1690.1579 1721.5784 1775.5948 1826.0298 1845.4012 10
Run Code Online (Sandbox Code Playgroud)
从data.table 1.9.8版本开始,eddi的解决方案需要修改为:
dups = duplicated(myDT, by = key(myDT));
myDT[, fD := dups | c(tail(dups, -1), FALSE)]
Run Code Online (Sandbox Code Playgroud)
自从:
v1.9.8 中的更改(在 CRAN 2016 年 11 月 25 日)
潜在的突破性变化
默认情况下,所有列现在都由 unique()、duplicated() 和 uniqueN() data.table 方法使用,#1284 和 #1841。恢复旧行为:options(datatable.old.unique.by.key=TRUE)。在 1 年内,此恢复旧默认值的选项将被弃用并发出警告。2 年后,该选项将被删除。为清楚起见,请明确传递 by=key(DT)。只有依赖于默认值的代码会受到影响。在发布前检查了使用 data.table 的 266 个 CRAN 和 Bioconductor 包。9 需要更改并收到通知。这些检查将遗漏任何没有测试覆盖率的代码行。未检查任何不在 CRAN 或 Bioconductor 上的包裹。