如何精确搜索一个单词

8

我想在以下字符向量中搜索“氮”,并只返回包含“氮”的条目,而不包括其他内容(例如氮固定):

varnames=c("nitrogen", "dissolved organic nitrogen", "nitrogen fixation", "total dissolved nitrogen", "total nitrogen")

我尝试了以下的方法:
grepl(pattern= "![[:space:]]nitrogen![[:space:]]", varnames)

但是这种方法不起作用。

8
你是想获得值恰好等于“氮”的索引/指数吗?which(varnames == "nitrogen") 是否能满足你的需求? - Dason
Dason:你能把你的评论变成一个答案,这样Sabsirro就可以接受了吗? - Carl Witthoft
3个回答

14

虽然Dason的回答更简单,但也可以通过grep进行精确匹配:

varnames=c("nitrogen", "dissolved organic nitrogen", "nitrogen fixation", "total dissolved nitrogen", "total nitrogen")

grep("^nitrogen$",varnames,value=TRUE)
[1] "nitrogen"

grep("^nitrogen$",varnames)
[1] 1

2
丹森的答案不仅更简单,而且更快。 - Joshua Ulrich
它能工作,但速度很慢。除非你正在动态构建正则表达式,否则没有必要使用“^someword$”。 - aL3xa

13

要获取与“nitrogen”完全相等的索引,您可以使用

which(varnames == "nitrogen")

根据您想要做的事情,您甚至可能不需要使用'which',因为varnames == "nitrogen"会给出TRUE / FALSE的逻辑向量。如果您只想做一些替换所有出现的“nitrogen”为“oxygen”的操作,那么这应该就足够了。

varnames[varnames == "nitrogen"] <- "oxygen"

2

如果您想匹配实际字符串(无需使用正则表达式),可以使用 fixed = TRUE

v <- sample(c("nitrogen", "potassium", "hidrogen"), size = 100, replace = TRUE, prob = c(.8, .1, .1))
grep("nitrogen", v, fixed = TRUE)
# [1]   3   4   5   6   7   8   9  11  12  13  14  16  19  20  21  22  23  24  25
# [20]  26  27  29  31  32  35  36  38  39  40  41  43  44  46  47  48  49  50  51
# [39]  52  53  54  56  57  60  61  62  65  66  67  69  70  71  72  73  74  75  76
# [58]  78  79  80  81  82  83  84  85  86  87  88  89  91  92  93  94  95  96  97
# [77]  98  99 100

不太清楚速度问题,我喜欢测试并声称方法A比方法B更快,但从我的经验来看,至少在理论上,索引/二进制运算符应该是最快的,所以我投票支持@Dason的方法。另请注意,正则表达式总是比fixed=TRUE的grep()慢。
下面附有一些证明。请注意,这是一个简单的测试,应该将system.time放置在replicate内以获得(更多)准确的差异,您应该考虑异常值等。但是这肯定证明了您应该使用which!=)
(a0 <- system.time(replicate(1e5, grep("^nitrogen$", v))))
# user  system elapsed 
# 5.700   0.023   5.724  
(a1 <- system.time(replicate(1e5, grep("nitrogen", v, fixed = TRUE))))
# user  system elapsed 
# 1.147   0.020   1.168 
(a2 <- system.time(replicate(1e5, which(v == "nitrogen"))))
# user  system elapsed 
# 1.013   0.020   1.033 

谢谢你提供如此详细的答案,了解这些差异很有帮助。 - sabsirro

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