如何反转dplyr :: select的辅助函数?

cra*_*lly 6 r dplyr

如何反转辅助函数dplyr::select()(如matches()contains()),以便我可以选择不包含或匹配特定字符串的变量?

例如,假设我想选择mtcars数据框中没有字母"m"的所有列.我可以想象做类似的事情:

mtcars %>%
    select( !matches("m") )
Run Code Online (Sandbox Code Playgroud)

但是这会引发错误:

Error: !matches("m") must resolve to integer column positions, not a logical vector

如何编写辅助函数来反转它?

重要提示:一种可能性是使用matches()和编写一个不匹配的正则表达式,但我更感兴趣的是找到一种方法来维护辅助函数的简单性,但是反转它们返回的选择,而不是解决实际的"我如何选择这样的"问题.

cra*_*lly 14

为辅助功能select()matches(),contains(),starts_with()等等,返回的索引值的向量.在上面的例子中,如果我们不想反转,matches("m")将返回,c(1,9)因为第一和第九列名称包含"m".

考虑到这一点,我们所要做的就是使功能变为负面:

mtcars %>%
    select( -matches("m") )
Run Code Online (Sandbox Code Playgroud)

这使得matches("m")返回一个向量c(-1, -9),取消选择那些列,但保留其他所有列.

使用!,布尔值NOT,如原始示例中所示,将整数值强制转换为逻辑,因此c(1,9),最终c(FALSE, FALSE)由于1和9都强制转换TRUE,然后被转换为!.

这解释了R抛出的错误 - select()想要一个整数列表,对应于列索引,而不是逻辑值的向量.