使用dplyr中的contains()函数基于多个字符串选择列

59

我想基于正则表达式选择多列,采用 dplyr 包的管道语法实现。我查看了其他话题,但只找到了有关单个字符串的答案。

使用基本 R:

library(dplyr)    
mtcars[grepl('m|ar', names(mtcars))]
###                      mpg am gear carb
### Mazda RX4           21.0  1    4    4
### Mazda RX4 Wag       21.0  1    4    4

然而,它不能与select/contains方法一起使用:

mtcars %>% select(contains('m|ar'))
### data frame with 0 columns and 32 rows

有什么问题吗?

4个回答

114

你可以使用 matches

 mtcars %>%
        select(matches('m|ar')) %>%
        head(2)
 #              mpg am gear carb
 #Mazda RX4      21  1    4    4
 #Mazda RX4 Wag  21  1    4    4

根据?select文档

‘matches(x, ignore.case = TRUE)’:选择所有变量名称与正则表达式‘x’匹配的变量。

contains虽然仅适用于单个字符串。

mtcars %>% 
       select(contains('m'))

1
谢谢@akrun,我现在感觉很愚蠢:-)。但是还有一个问题:既然如此,为什么我们甚至要使用contains(),如果matches()做得更好呢? - agenis
6
因为您可能想匹配“.”并且不必考虑在正则表达式中如何转义它,所以需要这么做。 - hadley
3
在这种情况下,您可以使用 paste 函数,即 paste(yourvec, collapse="|"),并将其用于 matches 函数。 - akrun
1
akrun,非常感谢。我已经进行了很多挖掘和实验。祝一切顺利。 - Michael Bellhouse
1
equivalent_for_filter <- df %>% filter(!grepl(paste(exclude_filter, collapse="|"),variable))等效的筛选语句为:equivalent_for_filter <- df %>% filter(!grepl(paste(exclude_filter, collapse="|"),variable)) - Michael Bellhouse
显示剩余4条评论

21
您可以使用dplyr包中的contains函数,只需提供一个文本向量即可,例如:

mtcars %>% 
       select(contains(c("m", "ar"))

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community
1
contains()函数与一个包含任意数量元素的向量一起使用非常好用。实际上,matches()应该保留用于需要使用正则表达式进行复杂匹配的情况。 - Faustin Gashakamba

4

你仍然可以使用来自基本R的grepl()

df <- mtcars[ , grepl('m|ar', names(mtcars))]

...这将返回一个子数据框df,其中包含列名中包含mar的列


1

这里有一个替代方案

mtcars %>% 
    select(contains('m') | contains('ar')) %>% 
    head(2)

#             mpg am gear carb
# Mazda RX4      21  1    4    4
# Mazda RX4 Wag  21  1    4    4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接