如何测试 R 中一系列列的条件

ash*_*ych 4 if-statement r

我正在尝试测试一系列列中的条件。数据看起来像这样

      Name DPD_1 DPD_2 DPD_3 Default_flag
 1:    A    46    63   138         TRUE
 2:    B    12    82    33        FALSE
 3:    C    95    71    55         TRUE
 4:    D    57   133   116         TRUE
 5:    E    48    27   137         TRUE
Run Code Online (Sandbox Code Playgroud)

在代码中,我需要测试 DPD_1、DPD_2 或 DPD_3 中的任何一个是否大于 90,在这种情况下 Default_flag 设置为 TRUE。

我为此使用的代码如下

df1 <- data.table(Name = LETTERS[1:10],DPD_1 = sample(1:100,10),DPD_2 = sample(1:200,10),DPD_3 = sample(1:200,10) )
df1[,Default_flag := ifelse((DPD_1>=90 | DPD_2>=90 | DPD_3>=90 ),TRUE,FALSE)]
Run Code Online (Sandbox Code Playgroud)

现在问题出在一些数据集上,我需要将 DPD 检查从 DPD_1 增加到 DPD_24(检查 24 列,而不是当前示例中的 3 列)。无论如何我可以避免在 ifelse 语句中指定每个 DPDnumber。我很高兴失去 ifelse 语句,如果某些版本的 apply 可以工作,我也很乐意使用它。

akr*_*run 5

我们可以在指定感兴趣的列之后使用Reducewith|.SDcols

df1[, Default_flag :=  Reduce(`|`, lapply(.SD, `>=`, 90)), .SDcols = DPD_1:DPD_3]
Run Code Online (Sandbox Code Playgroud)

更新

根据OP的评论,如果我们需要创建一个函数来自动检测列名,则使用grep基于模式获取列名。下面的函数采用数据集、模式('pat')、要比较的值('val')和'n',即特定模式的列数

f1 <- function(dat, pat, val, n){
  tmp <- as.data.table(dat)
  nm1 <- head(grep(pat, names(tmp), value = TRUE), n)
  tmp[, Default_flag := Reduce(`|`,lapply(.SD, `>=`, val)), .SDcols = nm1][]
}

f1(df1, "DPD", 90, 2)
f1(df1, "DPD", 90, 3)
Run Code Online (Sandbox Code Playgroud)

根据@aelwan 的请求,使用的选项tidyverse

library(tidyverse)
f2 <- function(dat, pat, val, n){
  pat <- quo_name(enquo(pat))
  nm1 <- head(grep(pat, names(dat), value = TRUE), n)

  dat %>%
      mutate_at(vars(nm1), funs(.>= val)) %>%
      select_at(nm1) %>%
      reduce(`|`) %>%
      mutate(dat, Default_flag = .) 

}

f2(df1, DPD, 90, 2)
f2(df1, DPD, 90, 3)
Run Code Online (Sandbox Code Playgroud)
identical(f1(df1, "DPD", 90, 2), as.data.table(f2(df1, DPD, 90, 2)))
#[1] TRUE
identical(f1(df1, "DPD", 90, 3), as.data.table(f2(df1, DPD, 90, 3)))
#[1] TRUE
Run Code Online (Sandbox Code Playgroud)