Этот вопрос похож на
семантика ссылки на data.table: использование памяти для итерации по всем столбцам
, но обсуждается немного другая настройка, поэтому я решил оставить их отдельно.
При замене всех столбцов в таблице data.table путем применения функции my_fun
к каждому столбцу в сочетании с группировкой строк с использованием аргумента by
, что примерно происходит в параметре типа
library(data.table)
dt <- data.table(a = 1L:10L, b = 11L:20L, c = rep(LETTERS[1:2], each = 5))
my_fun <- function(x) x + 1L
dt[, c("a", "b") := lapply(.SD, my_fun), by = "c", .SDcols = c("a", "b")]
(1) Проблема сначала разбивается на группы, и для каждой группы оценивается lapply(.SD, my_fun)
. Прежде чем перейти к следующей группе, результаты записываются в dt
. Согласно указанному вопросу , объем памяти в этом случае составляет приблизительно max (n_rows на группу) x (n_cols in .SD
) x sizeof (data_type)
(2) Проблема разбита на группы и для каждой группы оценивается lapply(.SD, my_fun)
. По завершении итерации по всем группам результат записывается в соответствующие столбцы в dt
. В этом случае накладные расходы памяти составляют приблизительно (n_rows в dt
) x (n_cols in .SD
) x sizeof (data_type)
(3) Проблема решается по принципу столбец за столбцом, и для каждого столбца столбец разбивается, и для каждого подмножества текущего столбца вызывается my_fun
. После завершения с полным столбцом результаты записываются в dt
. Это может привести к накладным расходам (примерно n_rows in dt
) x sizeof (data_type).
(4) Что-то еще?
Из ответа в вопрос, упомянутый выше , (3), может быть включен в будущем посредством оптимизации, аналогичной описанной в ?datatable.optimize
в разделе уровня 1, но в настоящее время (v1.11.4 ) недоступен.
Причина, по которой я задаю этот вопрос, заключается в том, что, особенно если в настройке (2), а в некоторых случаях, возможно, также в настройке (1), имеет смысл каким-то образом принудительно применять подход столбец за столбцом.
К сожалению, в дальнейшем не работает, так как set()
не поддерживает группировку.
for (col in c("a", "b")) set(dt, j = col, value = my_fun(dt[[col]]), by = "c")
Кроме того, что-то вроде
lapply(c("a", "b"), function(col) dt[, (col) := my_fun(dt[[col]]), by = "c"])
не работает, так как вложенное подмножество dt[[col]]
не разбивается. Есть ли другой способ добиться того, что я пытаюсь сделать, используя data.table
?