Я ищу способ умножить несколько столбцов data.table на несколько других столбцов в том же DT. Другой пост был посвящен способу умножения многих столбцов на столбец конкретный в том же DT Умножить много столбцов на конкретный другой столбец в R с data.table?. Мой вопрос расширяет предыдущий вопрос.
Начиная с этого ОУ:
DT <- data.table(x1 = 1:5L, y1 = 6:10L, x2 = 11:15L, y2 = 16:20L)
x1 y1 x2 y2
1: 1 6 11 16
2: 2 7 12 17
3: 3 8 13 18
4: 4 9 14 19
5: 5 10 15 20
Я хочу перемножить z1 = x1 * y1 и z2 = x2 * y2, чтобы получить
x1 y1 x2 y2 z1 z2
1: 1 6 11 16 6 176
2: 2 7 12 17 14 204
3: 3 8 13 18 24 234
4: 4 9 14 19 36 266
5: 5 10 15 20 50 300
Вот способ построения желаемого DT методом грубой силы:
DT2[, ':='(z1 = x1 * y1, z2 = x2 * y2]
Конечно, должен существовать элегантный способ сделать это.





Я нашел этот ответ R data.table вычисляет новые столбцы в lapply, выполнив поиск по тегам "data.table" + "calculate-columns". В более широком смысле, ответ на мой вопрос будет таким:
DT <- data.table(x1 = 1:5L, y1 = 6:10L, x2 = 11:15L, y2 = 16:20L)
FUN <- function(ndx, DT) {DT[, paste("z", ndx, sep = "") := get(paste("x", ndx, sep = "")) * get(paste("y", ndx, sep = ""))]}
lapply(1:2, FUN, DT)
DT
x1 y1 x2 y2 z1 z2
1: 1 6 11 16 6 176
2: 2 7 12 17 14 204
3: 3 8 13 18 24 234
4: 4 9 14 19 36 266
5: 5 10 15 20 50 300
Хотя это, очевидно, ответ, возможно, понятно, почему я не смог его найти, потому что я думаю, что в названии нет конкретики. Тем не менее, есть ли более простой способ подойти к поставленному здесь вопросу?
Вероятно, дело вкуса, но вы могли бы использовать Map и составить несколько списков для его подачи.
DT[, c("z1", "z2") := Map("*", list(x1, x2), list(y1, y2))]
Расширяясь до многих переменных в сочетании с mget и ls, сделайте
DT[, c("z1", "z2") := Map("*", mget(ls(pattern = "x")), mget(ls(pattern = "y")))]
Оба они возвращают желаемый результат
DT
x1 y1 x2 y2 z1 z2
1: 1 6 11 16 6 176
2: 2 7 12 17 14 204
3: 3 8 13 18 24 234
4: 4 9 14 19 36 266
5: 5 10 15 20 50 300
Я просто упомяну, что mget и ls с шаблонами можно использовать для возврата списков объектов, существующих в определенной среде. ls по умолчанию выполняет поиск в родительской среде, которая является средой data.table, в которой он был вызван. Таким образом, в случае, когда у вас есть объект с именем x3, который существует вне таблицы data.table, вам не о чем беспокоиться: этот объект игнорируется.