dplyr mutate,应用将变量(或对象,向量)合并到感兴趣的数据框之外的函数

dplyr mutate, applying functions that incorporate variables (or objects, vectors) outside the data frame of interest

问题

我很好奇如何将函数应用于 dplyr 中的 mutate 函数,这需要一个参数,该参数是我在别处定义的向量。

我有一个示例,它从我实际尝试做的事情中抽象出来(我正在使用多个列,检查该行的那些列中是否存在值取决于 [=48 的日期=],然后 return 一个字符串分类),但是为了简洁起见,下面的示例会产生相同的错误,但愿它足够了。

设置

DF <- data.frame(
  Index = 1:100, 
  Num1 = runif(100,0,100) %/% 1
  )

# array to check
CheckArray = seq(0,100, by = 2)

f <- function(x, ArrayToCheck){
  if (x %in% ArrayToCheck){
    return(T)
  } else {
    return(F)
  }
}

我的尝试

DF <- dplyr::mutate(
  DF,
  Num1_even = f(Num1, CheckArray)
  )

这当然是 return 一个错误

Warning message: In if (x %in% ArrayToCheck) { : the condition has length > 1 and only the first element will be used*

补充说明

我应该指出,我知道我的示例可以在没有函数的情况下通过其他方式解决,例如

dplyr::mutate(
  DF,
  Num1_even = Num1 %in% CheckArray
)

dplyr::mutate(
     DF,
     Num1_even = Num1 %in% seq(0,100, by = 2)
)

但在这种情况下和许多其他情况下,我经常发现在我的 DF 之外定义一个向量很有价值,然后将一个函数与多个附加参数一起应用于每一行。

我也看到通过 apply 函数族解决了这个问题,但我希望 dplyr 中有一个方法,因为它是如此之快并且具有如此好的语法。


也许我们可以让 Hadleyverse 添加一个运算符,告诉 dplyr 跳出当前 data.frame 的范围,例如

CheckArray = seq(0,100, by = 2)

DF <- dplyr::mutate(
  DF,
  Num1_even = f(Num1, %o%CheckArray%o%)
  )

这与CheckArray向量无关。问题是 if 语句在 R 中没有向量化。您可以改用 ifelse。然后你的电话应该工作。查看 ?ifelse 了解更多信息。

f <- function(x, ArrayToCheck){
  ifelse(x %in% ArrayToCheck, TRUE, FALSE)
}

dplyr::mutate(
  DF,
  Num1_even = f(Num1, CheckArray)
)

当然在这种情况下 ifelse 实际上也不需要(见下文)。如果您想要的输出仅包含 TRUEFALSE,您可以跳过 ifelse,但我添加了 ifelse 以防您的实际示例比这更复杂。

f <- function(x, ArrayToCheck){
  x %in% ArrayToCheck
}