я делаю что-то неправильно ИЭ следует избегать .SD
в пользу отдельных столбцов?
Да, точно. Используйте только .SD
, если вы действительно используете все данные внутри .SD
. Вы также можете обнаружить, что вызов nrow()
и вызов подзапроса [.data.table
внутри j
также являются преступниками: используйте Rprof
для подтверждения.
Смотрите последние несколько предложений часто задаваемых вопросов 2.1:
FAQ 2.1 Как я могу избежать написания действительно длинное выражение J? Вы сказали, что я должен использовать имена столбцов, но у меня много столбцов.
При группировке, выражение j
можно использовать имена столбцов в качестве переменных, так как вы знаете, но он также может использовать зарезервированный символ .SD
, который относится к Подмножеству Data.table для каждой группы (за исключением группировки столбцов). Итак, чтобы подвести итог всем вашим колонкам, это всего лишь 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
). Однако, если вам все это нужно, это не имеет значения, например, в DT[,lapply(.SD,sum),by=...]
. Это идеальное использование .SD
.
Итак, да, избегайте .SD
, где это возможно. Используйте имена столбцов напрямую, чтобы дать оптимизацию data.table j
. Важное значение имеет простое существование символа .SD
в j
.
Именно поэтому .SDcols
был введен. Поэтому вы можете указать data.table
, какие столбцы должны быть в .SD
, если вы хотите только подмножество. В противном случае data.table
заполнит .SD
со всеми столбцами на всякий случай j
нуждается в них.
Спасибо большое! Я был обманут фразой «Объект .SD эффективно реализован внутренне и более эффективно, чем передача аргумента функции», и не понял «Пожалуйста, не делайте этого, хотя: DT [, sum (.SD [,» sales ", with = FALSE]), by = grp]" из-за with = FALSE. Это ускорит мой код! – vsalmendra
@ vsalmendra А, да, это может быть яснее. Это то, что было оставлено на обсуждение сообщества в прошлом. В конечном итоге мы надеемся улучшить оптимизацию 'j', чтобы пользователям не нужно было разбираться в таких вещах. –
@vsalmendra Теперь я улучшил FAQ 2.1 для следующего выпуска. –