Ответ 1
Я делаю что-то неправильно, я должен избегать
.SD
в пользу отдельных столбцов?
Да, точно. Используйте .SD
только, если вы действительно используете все данные внутри .SD
. Вы также можете обнаружить, что вызов nrow()
и вызов подзапроса на [.data.table
внутри j
тоже являются преступниками: используйте Rprof
для подтверждения.
См. последние несколько предложений FAQ 2.1:
FAQ 2.1 Как я могу избежать написания действительно длинного j выражения? Вы сказали, что я должен использовать имена столбцов, но у меня есть много столбцов.
При группировке выражениеj
может использовать имена столбцов в качестве переменных, как вы знаете, но он также может использовать зарезервированный символ.SD
, который ссылается на подмножество таблицы данных для каждой группы (исключая группировку колонны). Итак, чтобы подвести итоги всех ваших столбцов, простоDT[,lapply(.SD,sum),by=grp]
. Это может показаться сложным, но быстро писать и быстро запускать. Обратите внимание, что вам не нужно создавать анонимные функция. См. Временную виньетку и вики для сравнения с другими методы. Объект.SD
эффективно реализуется внутренне и более чем передача аргумента функции. Пожалуйста, не делайте этого хотя:DT[,sum(.SD[,"sales",with=FALSE]),by=grp]
. Это работает, но очень неэффективен и неэффективен. Вот что было предназначено:DT[,sum(sales),by=grp]
и может быть в 100 раз быстрее.
Также см. первый пул FAQ 3.1:
FAQ 3.1 У меня есть 20 столбцов и большое количество строк. Почему выражение одного столбца так быстро?
Несколько причин:
- Только эта колонка сгруппированы, остальные 19 игнорируются, потому чтоdata.table
проверяетj
выражение и понимает, что он не использует другие столбцы.
Когда data.table
проверяет j
и видит символ .SD
, это повышение эффективности выходит из окна. Он должен будет заполнить все подмножество .SD
для каждой группы, даже если вы не используете все его столбцы. Для data.table
очень сложно узнать, какие столбцы .SD
вы действительно используете (j
может содержать if
s, например). Однако, если вам все это нужно, это, конечно, не имеет значения, например, в DT[,lapply(.SD,sum),by=...]
. Это идеальное использование .SD
.
Итак, да, избегайте .SD
, где это возможно. Используйте имена столбцов напрямую, чтобы обеспечить оптимальную оптимизацию
j
. Важное значение имеет простое существование символа .SD
в j
.
Вот почему .SDcols
был введен. Поэтому вы можете указать data.table
, какие столбцы должны быть в .SD
, если вы хотите только подмножество. В противном случае data.table
будет заполнять .SD
всеми столбцами на всякий случай, если требуется j
.