Расширение комментариев.
Из поста Аруна в Какова цель установки ключа в data.table? , которую Фрэнк предоставил в комментарии:
Даже в противном случае, если вы не выполняете объединения повторно, не должно быть заметной разницы в производительности между соединениями с ключом и специальными соединениями.
и
Поэтому важно выяснить, стоит ли время, затрачиваемое на переупорядочение всей таблицы данных, время, затрачиваемое на объединение / агрегирование с эффективным использованием кэша.Обычно, если нет повторяющихся операций группирования / объединения, выполняемых с одним и тем же ключом data.table, заметного различия не должно быть.
Следовательно, данные OP быстро и эффективно обрабатываются.Решение в стиле таблицы действительно зависит от размерности проблемы, то есть от размера набора данных и количества выполненных поисков.
Вот некоторые временные параметры, если оба они велики:
данные:
library(data.table)
set.seed(0L)
M <- 1e7
dtKeyed <- data.table(x=1:M, y=2:(M+1)) #R-3.4.4 data.table_1.10.4-3 win-x64
dtNoKey <- copy(dtKeyed)
system.time(setkey(dtKeyed, x, y)) #not free
dtKeyed
nsearches <- 1e3
points <- apply(matrix(sample(M, nsearches*2, replace=TRUE), ncol=2), 1, as.list)
вариации:
findPtNoKey <- function() {
lapply(points, function(p) dtNoKey[p, on=names(dtNoKey), .N > 0, nomatch=0])
}
findPtOnKey <- function() {
lapply(points, function(p) dtKeyed[p, on=names(dtKeyed), .N > 0, nomatch=0])
}
findPtKeyed <- function() {
lapply(points, function(p) dtKeyed[p, .N > 0, nomatch=0])
}
library(microbenchmark)
microbenchmark(findPtKeyed(), findPtOnKey(), findPtNoKey(), times=3L)
время:
#rem to add back the timing from setkey into the timing for findPtKeyed
Unit: milliseconds
expr min lq mean median uq max neval
findPtKeyed() 924.6846 928.3025 946.0892 931.9205 956.7914 981.6624 3
findPtOnKey() 1119.9686 1129.5641 1143.4505 1139.1597 1155.1915 1171.2233 3
findPtNoKey() 146186.2216 154934.5463 161016.1277 163682.8709 168431.0807 173179.2905 3
проверки точности:
ref <- findPtNoKey()
identical(findPtKeyed(), ref)
#[1] TRUE
identical(findPtOnKey(), ref)
#[1] TRUE