Eine weitere Option ist eine vorwärts-
indx <- sort.int(dt[unique(dt), on = c(x = "y", y = "x"), which = TRUE, nomatch = 0L])
dt[indx]
# x y
# 1: 1 4
# 2: 4 1
# 3: 6 2
# 4: 2 6
dt[-indx]
# x y
# 1: 3 7
# 2: 5 1
Benchmark sich verbinden ausführen - Wenn Sie nicht über die Reihenfolge egal , meine Lösung scheint für 200MM Reihen schneller zu sein (beide Lösungen sind ungeordnet)
set.seed(123)
bigdt <- data.table(x = sample(1e3, 2e8, replace = TRUE),
y = sample(1e3, 2e8, replace = TRUE))
system.time(i1 <- bigdt[, .I[.N>1] ,.(X=pmax(x,y), Y=pmin(y,x))]$V1)
# user system elapsed
# 21.81 0.82 22.97
system.time(indx <- bigdt[unique(bigdt), on = c(x = "y", y = "x"), which = TRUE, nomatch = 0L])
# user system elapsed
# 17.74 0.90 18.80
# Checking if both unsorted and if identical when sorted
is.unsorted(i1)
# [1] TRUE
is.unsorted(indx)
# [1] TRUE
identical(sort.int(i1), sort.int(indx))
# [1] TRUE
Und hier ist ein nicht-entarteter Fall (wo indx != bigdt[, .I]
):
set.seed(123)
n = 1e7
nv = 1e4
DT <- data.table(x = sample(nv, n, replace = TRUE), y = sample(nv, n, replace = TRUE))
library(microbenchmark)
microbenchmark(
akrun = {
idx = DT[, .I[.N > 1], by=.(pmax(x,y), pmin(x,y))]$V1
list(DT[idx], DT[-idx])
},
akrun2 = {
idx = DT[,{
x1 <- paste(pmin(x,y), pmax(x,y))
duplicated(x1)|duplicated(x1, fromLast=TRUE)
}]
list(DT[idx], DT[!idx])
},
davida = {
idx = DT[unique(DT), on = c(x = "y", y = "x"), which = TRUE, nomatch = 0L]
list(DT[idx], DT[-idx])
},
akrun3 = {
n = DT[, N := .N, by = .(pmax(x,y), pmin(x,y))]$N
DT[, N := NULL]
split(DT, n > 1L)
}, times = 1)
Unit: seconds
expr min lq mean median uq max neval
akrun 7.056609 7.056609 7.056609 7.056609 7.056609 7.056609 1
akrun2 22.810844 22.810844 22.810844 22.810844 22.810844 22.810844 1
davida 2.738918 2.738918 2.738918 2.738918 2.738918 2.738918 1
akrun3 5.662700 5.662700 5.662700 5.662700 5.662700 5.662700 1
Ich denke, Sie sollten mit einem Beispiel testen, das nicht identisch (Sortierung (Indx), Bigdt [, .I]) # TRUE' – Frank
Ich habe eine, wird bearbeiten. Ihr entpuppt sich in meinem Beispiel zu gewinnen. – Frank
Vielen Dank David. Nur auf eine Randnotiz (was nicht der Fall ist, ich interessiere mich), Arkun Lösung ist erweiterbar Triplets (oder Tupel im Allgemeinen), anstatt Paare. Wechseln Sie einfach pmin(), pmax() mit sort(). Ihre Lösung verlangt, dass ich mich in der on = c() Phase nur an eine mögliche Permutation der Werte in jeder Zeile halte. – Amitai