Каков рекомендуемый / «лучший» способ (по производительности) для фильтрации data.table
на основе некоторых критериев, рассчитанных для агрегированной формы этой самой таблицы.
A reprex
говорит более 1000 слова:
library(data.table)
DT <- data.table(grp = rep(LETTERS[1:3], each = 3), x = 1:9)
setkey(DT, "grp")
DT[DT[, .(nok = any(x == 4)), by = grp][nok == FALSE]]
DT[DT[, .GRP[all(x != 4)], by = grp]]
Я мог бы сразу подумать об этих 2 решениях, и мое внутреннее чувство подсказывает мне, что вторая форма должна быть «лучше» (меньшие промежуточные таблицы хранятся, и мне не нужно связывать результаты), но мне было интересно, есть ли каноническая форма выполнения этого?
Может быть, мне не нужно использовать объединение в первую очередь и могу использовать сгруппированный фильтр для аргумента i
?
Это, очевидно, не работает должным образом (by
, очевидно, оказывает влияние только на j
):
DT[all(x != 4), by = grp]
В то время как этот SO ответ показывает еще один способ делать то же самое, моя главная забота о производительности. Таким образом, я хотел бы знать, какая из этих опций будет хорошо масштабироваться для больших таблиц, если я хочу продолжить работу с отфильтрованной таблицей data.table (то есть использовать другое выражение j
для отфильтрованного результата)
В моем реальном случае у меня есть около 16 строк Mio, около 40 000 уникальных ключей и 14 столбцов.
Таким образом, набор эталонных данных может выглядеть следующим образом:
bench <- data.table(keys = rep(paste0("k", 1:40000), 400))
bench[, paste0("cols", 1:13) := replicate(13, sample(40000 * 400, TRUE),
simplify = FALSE)]
Пока я ищу обобщенный c ответ (если возможно) независимо от выбранного окончательного фильтра, фактический фильтр будет выяснить, какие группы содержат любое значение NA
.