在 mutate_if 的 .predicate 参数中正确使用 rlang::as_function 公式

Correctly using rlang::as_function formula within .predicate argument of mutate_if

我想按以下方式在 mutate_if.predicate 参数中使用 ~ . %% 1 == 0 公式:

dta %>%
    mutate_if(.predicate =  ~ . %% 1 == 0,
              .funs = funs(. + 10))

其中 dta 对应于以下标题:

dta <- tibble(colA = c("a", "b"),
              colB = 1:2,
              colC = c(1.1, 2.2))

这当前会产生以下错误:

Error in .%%1 : non-numeric argument to binary operator

背景

dplyr::mutate_if 的文档中指出:

.predicate A predicate function to be applied to the columns or a logical vector. The variables for which .predicate is or returns TRUE are selected. This argument is passed to rlang::as_function() and thus supports quosure-style lambda functions and strings representing function names.

因此,公式 ~ . %% 1 == 0 可以按以下方式使用:

f_rlang_check <- rlang::as_function( ~ . %% 1 == 0)

f_rlang_check(c(1.1, 1))
[1] FALSE  TRUE

显然公式是正确的;但是,它不能直接传递给 rlang::as_function(),如上所示。

dta %>%
    mutate_if(.predicate = f_rlang_check,
              .funs = funs(. + 10))

产生相同的错误

mutate_if 将尝试计算所有列的谓词函数,因此在尝试将二元运算符 %% 与非数字参数 colA 一起使用时会出现错误。您可以使用 is.numeric&& 来解决这个问题。

谓词应该return一个单一的逻辑值,所以你可能想使用allany

dta %>%
    mutate_if(.predicate = ~ is.numeric(.) && all(. %% 1 == 0),
              .funs = funs(. + 10))