динамически обновлять / объединять несколько столбцов в таблице поиска

Вот игрушечный пример табличного unit с двумя столбцами, к которому я хочу динамически присоединиться к таблице поиска mult . Я могу сделать это, написав все это:

unit[mult, mul1 := i.multiplier, on = c(uni1 = 'unit') ]
unit[mult, mul2 := i.multiplier, on = c(uni2 = 'unit') ]

Однако я хочу сделать это динамически, поскольку в моей таблице реальных unit число столбцов может варьироваться. Могу ли я выполнить это объединение динамически?

Я пробовал это, но я борюсь с аргументом on = :

for (j in seq_along(names(unit))) {
  col = names(unit)[j]
  unit[mult, paste0('mul', j) := i.multiplier, on = c(col = 'unit') ]
}

Данные:

unit = data.table(
uni1 = c("ug", "mg", "ppm", "kg", "kg", "uM",
           "mg", "lb", "%", "g"),
  uni2 = c("L", "L", NA, "ha", "ha", NA,
           "kg", "acre", NA, "ha")
)
mult = data.table(
  unit = c("ug", "mg", "g", "kg", "L", "ppm", "uM",
           "ha", "acre", "%", "lb"),
  multiplier = c(1e-06, 0.001, 1, 1000,
                 1, 1000, 1e-06, 10000, 4050, 1e+07, 453.592)
)

Всего 2 ответа


Альтернативой объединению является сопоставление соответствующих .SD с использованием функции, примененной по столбцам с использованием .SD .

mulcol = paste0('mul', 1:ncol(unit))

unit[, (mulcol) := lapply(.SD, function(x){
  sapply(x, function(y) mult[unit == y, multiplier])
})]

Выход:

> unit
    uni1 uni2        mul1  mul2
 1:   ug    L 1.00000e-06     1
 2:   mg    L 1.00000e-03     1
 3:  ppm <NA> 1.00000e+03      
 4:   kg   ha 1.00000e+03 10000
 5:   kg   ha 1.00000e+03 10000
 6:   uM <NA> 1.00000e-06      
 7:   mg   kg 1.00000e-03  1000
 8:   lb acre 4.53592e+02  4050
 9:    % <NA> 1.00000e+07      
10:    g   ha 1.00000e+00 10000

Единственное отличие состоит в том, что несуществующие uni2 оцениваются как numeric(0) вместо NA .


Я немного setkey() это решение, используя setkey() :

setkey(mult, 'unit')
for (j in seq_along(names(unit))) {
  col = names(unit)[j]
  setkeyv(unit, col)
  unit[mult, paste0('mul', j) := i.multiplier ]
}

Есть идеи?

10000