如何使用通配符识别字符串?
我找到glob2rx
,但我不太明白如何使用它。我尝试使用以下代码来选择以单词blue
开头的数据框行:
# make data frame
a <- data.frame( x = c('red','blue1','blue2', 'red2'))
# 1
result <- subset(a, x == glob2rx("blue*") )
# 2
test = ls(pattern = glob2rx("blue*"))
result2 <- subset(a, x == test )
# 3
result3 <- subset(a, x == pattern("blue*") )
然而,这些都没有奏效。我不确定我是否应该使用不同的功能来尝试这样做。
答案 0 :(得分:41)
如果要检查数据框内的元素,则不应使用ls()
,它仅查看当前工作空间中对象的名称(或者如果在当前环境中的函数内使用)。 ls()
不能看到此类对象中的Rownames或元素(除非您在ls(.)
- 调用中添加环境参数)。尝试使用grep()
这是用于角色向量模式匹配的主力函数:
result <- a[ grep("blue", a$x) , ] # Note need to use `a$` to get at the `x`
如果你想使用子集,那么可以考虑在子集参数中使用返回逻辑向量的密切相关的函数grepl()
:
subset(a, grepl("blue", a$x))
x
2 blue1
3 blue2
编辑:在subset()中添加一个“正确”使用glob2rx:
result <- subset(a, grepl(glob2rx("blue*") , x) )
result
x
2 blue1
3 blue2
在我回到这个问题之前,我认为我实际上并不理解glob2rx
。 (我确实理解了提问者难以解决的范围问题。任何阅读此内容的人现在应该向下滚动到Gavin的答案并提出它。)
答案 1 :(得分:31)
glob2rx()
将包含通配符的模式转换为等效的正则表达式。然后,您需要将此正则表达式传递给R的模式匹配工具之一。
如果您想匹配"blue*"
其中*
具有通常的通配符 not 正则表达式,则表示我们使用glob2rx()
将通配符模式转换为有用的正则表达式:
> glob2rx("blue*")
[1] "^blue"
返回的对象是正则表达式。
鉴于您的数据:
x <- c('red','blue1','blue2', 'red2')
我们可以使用grep()
或类似工具进行模式匹配:
> grx <- glob2rx("blue*")
> grep(grx, x)
[1] 2 3
> grep(grx, x, value = TRUE)
[1] "blue1" "blue2"
> grepl(grx, x)
[1] FALSE TRUE TRUE FALSE
关于您发布的选择行问题
> a <- data.frame(x = c('red','blue1','blue2', 'red2'))
> with(a, a[grepl(grx, x), ])
[1] blue1 blue2
Levels: blue1 blue2 red red2
> with(a, a[grep(grx, x), ])
[1] blue1 blue2
Levels: blue1 blue2 red red2
或通过subset()
:
> with(a, subset(a, subset = grepl(grx, x)))
x
2 blue1
3 blue2
希望能解释grob2rx()
做什么以及如何使用它?
答案 2 :(得分:4)
您走在正确的轨道上 - 您应该使用Google搜索的关键字是正则表达式。 R使用grep()
和其他一些替代方案以比这更直接的方式支持它们。
答案 3 :(得分:2)
如果您确实想要使用通配符来识别特定变量,那么您可以使用ls()
和grep()
的组合,如下所示:
l = ls()
vars.with.result <- l[grep("result", l)]
答案 4 :(得分:2)
你也可以使用package data.table和它的Like函数,详情如下 How to select R data.table rows based on substring match (a la SQL like)
答案 5 :(得分:0)
实现所需功能的另一种方法是通过 dplyr()
filter(str_detect(a, "blue"))
它将考虑 blue 的所有实例,例如 blue1 和 blue2
这个命令与
基本相同filter(str_detect(a, "blue") == TRUE)
如果蓝调是大写和小写,您可以执行以下操作:
filter(str_detect(str_to_lower(a), "blue"))
我希望它可以帮助正在寻找类似解决方案的人。