Я могу предложить несколько предложений и, используя поддельные данные, опробовать их.
Вы можете программно определить имена в левой части :=
, если вы обернете вектор в c(...)
, например, DT[ c(vec_of_names) := list(some, values)]
.
Вы можете программно получать значения переменных с вектором имен переменных и mget
. Хотя я обычно думаю, что mget
может указывать на проблемный код c, я считаю, что здесь он работает с низким риском. (Хотя mget
и get
обычно извлекают переменные из операционной среды, часто .GlobalEnv
, из операции data.table
, а затем извлекают столбцы так же легко.)
Вместо этого двойного касания присваивания с помощью == 1
, а затем is.na(...)
, мы можем использовать некоторые логические уловки и функцию data.table::fcoalesce
. (Если вы не знакомы, fcoalesce
работает как функция coalesce SQL, которая представляет собой удобный для векторов способ поиска первого не- NA
значения в аргументах векторов.
fcoalesce(c(1, 2, NA, NA), c(11, 12, 13, NA), c(21, 22, 23, 24))
# [1] 1 2 13 24
Мы можем использовать fcoalesce(some + math * calc, 0)
для вычисления и, если NA
, заменить его на 0
. (Мы используем его для above*
переменных ниже, и не обязательно для логических переменных HCC*
. Он может примените и туда, если хотите. Если эти HCC*
переменные выбрасываются, это просто не имеет значения.)
Поддельные данные:
library(data.table)
set.seed(42)
hccthreshold <- 50
dat <- data.table( claim10month = sample(99, 10), claim11month = sample(99, 10), claim12month = sample(99, 10) )
dat$claim11month[5] <- NA
dat
# claim10month claim11month claim12month
# 1: 91 46 90
# 2: 92 71 14
# 3: 28 91 96
# 4: 80 25 91
# 5: 61 NA 8
# 6: 49 89 49
# 7: 69 97 37
# 8: 13 11 84
# 9: 60 95 41
# 10: 64 51 76
Во-первых, давайте программно определим имена столбцов, с которыми мы хотим работать, а затем создадим те же векторы для новых переменных (я большой поклонник определения и адаптации этих имен переменных программно, так что если вы получите частичный набор данных, ваш код по-прежнему работает. Вы можете подумать о настройке проверок и сигналов тревоги, чтобы обнаружить что-то не так. Например, stopifnot(length(claimnames) == 12L)
, если вы ожидаете, что всегда будет ровно 12 месяцев.)
claimnames <- grep("^claim[0-9]+month", colnames(dat), value = TRUE)
hccnames <- gsub("^claim", "HCC", claimnames)
abovenames <- gsub("^claim", "aboveHCC", claimnames)
claimnames
# [1] "claim10month" "claim11month" "claim12month"
hccnames
# [1] "HCC10month" "HCC11month" "HCC12month"
abovenames
# [1] "aboveHCC10month" "aboveHCC11month" "aboveHCC12month"
И теперь мы можем обработать t Данные.
dat[, c(hccnames) := lapply(mget(claimnames), `>`, hccthreshold) ]
dat[, c(abovenames) := Map(function(hcc, clm) fcoalesce(clm - hcc * hccthreshold, 0),
mget(hccnames), mget(claimnames)) ]
dat
# claim10month claim11month claim12month HCC10month HCC11month HCC12month aboveHCC10month aboveHCC11month aboveHCC12month
# 1: 91 46 90 TRUE FALSE TRUE 41 46 40
# 2: 92 71 14 TRUE TRUE FALSE 42 21 14
# 3: 28 91 96 FALSE TRUE TRUE 28 41 46
# 4: 80 25 91 TRUE FALSE TRUE 30 25 41
# 5: 61 NA 8 TRUE NA FALSE 11 0 8
# 6: 49 89 49 FALSE TRUE FALSE 49 39 49
# 7: 69 97 37 TRUE TRUE FALSE 19 47 37
# 8: 13 11 84 FALSE FALSE TRUE 13 11 34
# 9: 60 95 41 TRUE TRUE FALSE 10 45 41
# 10: 64 51 76 TRUE TRUE TRUE 14 1 26
Я решил оставить переменные HCC*
как logical
вместо ваших +(...)
целых чисел, но их можно напрямую переводить и решать вам.