将一系列条件函数应用于data.table

时间:2020-05-12 21:38:11

标签: r data.table

我需要对data.table上的几列应用一系列条件函数。 我是手动完成的,但要输入很多内容,如何将其变成一个更简单的函数?

dt_cases[
  , `:=`(cc_app_gt7 = fifelse(cc_app_min > 7, 1, 0),
         cc_app_gt30 = fifelse(cc_app_min > 30, 1, 0),
         cc_app_gt60 = fifelse(cc_app_min > 60, 1, 0),
         cc_app_gt90 = fifelse(cc_app_min > 90, 1, 0),
         cc_app_gt120 = fifelse(cc_app_min > 120, 1, 0),
         cc_app_gt180 = fifelse(cc_app_min > 180, 1, 0),
         cc_app_gt365 = fifelse(cc_app_min > 365, 1, 0),
         cn_gt7 = fifelse(cn_app_min > 7, 1, 0),
         cn_gt30 = fifelse(cn_app_min > 30, 1, 0),
         cn_gt60 = fifelse(cn_app_min > 60, 1, 0),
         cn_gt90 = fifelse(cn_app_min > 90, 1, 0),
         cn_gt120 = fifelse(cn_app_min > 120, 1, 0),
         cn_gt180 = fifelse(cn_app_min > 180, 1, 0),
         cn_gt365 = fifelse(cn_app_min > 365, 1, 0),
         daysdiff_gt7 = fifelse(days_diff > 7, 1, 0),
         days_diff_gt30 = fifelse(days_diff > 30, 1, 0),
         days_diff_gt60 = fifelse(days_diff > 60, 1, 0),
         days_diff_gt90 = fifelse(days_diff > 90, 1, 0),
         days_diff_gt120 = fifelse(days_diff > 120, 1, 0),
         days_diff_gt180 = fifelse(days_diff > 180, 1, 0),
         days_diff_gt365 = fifelse(days_diff > 365, 1, 0))
]

使用新的列名创建矢量很容易:

thresholds <- c(7, 30, 60, 90, 120, 180, 365)
cols_pref <- c("cc_app", "cn", "daysdiff")
eg <- expand.grid(cols_pref, thresholds)
cols <- paste0(eg$Var1, "_gt", eg$Var2)

还有我将要应用 fifelse 函数的列的向量:

vars <- c("cc_app_min", "cn_app_min", "days_diff")

但是我如何在不输入太多内容的情况下将所有这些东西混合到 fifelse 函数中呢?

谢谢!

2 个答案:

答案 0 :(得分:2)

以下是使用lapplysetNames的方法:

library(data.table)
thresholds <- c(7, 30, 60, 90, 120, 180, 365)
cols_pref <- c("cc_app", "cn", "daysdiff")
dt_cases[,lapply(.SD, function(x) as.data.table(
                                     setNames(lapply(thresholds,
                                                     function(y) as.integer(x > y))
                                              ,thresholds)))
         ,.SDcols = cols_pref]

名称之所以有所不同,是因为我利用了data.table重命名的内置列。

答案 1 :(得分:2)

如果我们要使用'eg'和'cols'

library(data.table)
dt_cases[, (cols) := Map(function(x, y) +(x > y), 
            mget(as.character(eg$Var1)), eg$Var2)]