Как выбрать строки по двум критериям в data.table в R
Скажем, у меня есть data.table, и я хочу выбрать все строки, где переменная x имеет значение b. Это легко
library(data.table)
DT <- data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
setkey(DT,x) # set a 1-column key
DT["b"]
Кстати, кажется, что нужно установить ключ, если ключ не установлен в x, тогда это не сработает. Кстати, что произойдет, если я установил два столбца в качестве ключей?
В любом случае, двигаясь вперед, скажем, что я хочу выбрать все строки, где переменная x была или b
DT["b"|"a"]
не работает
Но следующие работы
DT[x=="a"|x=="b"]
Но это использует векторное сканирование a la data frames. Он не использует двоичный поиск. Думаю, для небольших наборов данных это не имеет значения.
Это то, что я должен делать, или я не знаю синтаксиса data.table?
И еще одно. Существуют ли примеры более сложных логических процедур множественного выбора (или подмножества) с data.table?
Я знаю, что всегда мог вернуться к использованию функции subset(), так как data.table будет вести себя как data.frame, если это необходимо.
Ответы
Ответ 1
Вот путь, который только перешел мне в голову после того, как я задал вопрос, и он работает, но я не знаю, как это делается в тестах. Я не нахожусь на компьютере с установленным R. Я предполагаю, что я должен использовать экземпляр облака. Во всяком случае, мне нравится синтаксис
DT[c("a","b")]
Ответ 2
Использование оператора %in%
, по-видимому, дает коэффициент производительности 2. Рассмотрим:
library(data.table)
library(rbenchmark)
DT <- data.table(x=sample(letters, 1e6, TRUE), y=rnorm(1e6), v=runif(1e6))
setkey(DT,x) # set a 1-column key
DT["b"]
f1 <- function() DT[x %in% letters[1:2]]
f2 <- function() DT[x=="a"| x == "b"]
> benchmark(f1(),f2())
test replications elapsed relative user.self sys.self user.child sys.child
1 f1() 100 8.40 1.000000 7.58 0.81 NA NA
2 f2() 100 17.11 2.036905 15.54 1.56 NA NA
> all.equal(f1(), f2())
[1] TRUE
EDIT: добавление опции Farrel
Обратите внимание, что это на другом компьютере, но относительные удары одинаковы.
f3 <- function() DT[c("a", "b")]
test replications elapsed relative user.self sys.self user.child sys.child
1 f1() 100 11.281 7.121843 9.745 1.323 0 0
2 f2() 100 23.106 14.587121 20.824 2.224 0 0
3 f3() 100 1.584 1.000000 1.042 0.541 0 0