2012-03-09 85 views
0

几个月前,我结束了一个子语句,最初与我的输入数据一起工作。它已经停止工作,使我重新审视我的丑陋过程。我不想分享它,但它同时完成几件事情:替换和不匹配'sub'

active$id[grep("CIR",active$description)] <- sub(".*CIR0*(\\d+).*","\\1",active$description[grep("CIR",active$description)],perl=TRUE) 

此语句发现了嵌入在说明栏的ID行创建了一个新的ID列。子语句会查找“CIR0”后面的数字,并填充id列,如果在行描述中存在id的话。我认识到,在任务的任何一方嵌入grep子集都是低效的。

如果模式不匹配,有一种方法可以让'sub'替换为NA或为空吗?我觉得我错过了一些东西非常简单但要求社区的帮助。谢谢。

实例与创建一个id列结果:

| name | id | description  | 
|------+-----+-------------------| 
| a | 343 | Here is CIR00343 | 
| b |  | Didn't have it | 
| c | 123 | What is CIR| 
| d |  | CIR lacks a digit | 
| e | 452 | CIR452 is next | 
+2

如果你给出一些样本数据并输出,这将是很好的!这样我们可以验证你需要什么。 – nograpes 2012-03-09 21:12:57

+0

我相信自己这个问题已经足够普遍,以至于样本数据可能会更混乱,但您说得对 - 我添加了一个简短的表格。 – jed 2012-03-09 21:49:50

回答

1

几周前我在同一个问题上挣扎。我最终使用了stringr包中的str_match函数。如果没有找到目标字符串,它将返回NA。只要确保你正确地分组结果。举个例子:

library(stringr) 
str = "Little_Red_Riding_Hood" 
sub(".*(Little).*","\\1",str) # Returns 'Little' 
sub(".*(Big).*","\\1",str) # Returns 'Little_Red_Riding_Hood' 
str_match(str,".*(Little).*")[1,2] #Returns 'Little' 
str_match(str,".*(Big).*")[1,2] # Returns NA 
+0

感谢您向我介绍stringr软件包。使用它我已经能够清理流程并捕获我没有预料到的副案例。 – jed 2012-03-09 23:11:12

0

我觉得在这种情况下,你可以尝试使用ifelse(),即

active$id[grep("CIR",active$description)] <- ifelse(match, replacement, "") 

其中match应该评估为true,如果有一个匹配,并且replacement是在那种情况下将被替换的元素。同样,如果match的计算结果为false,则将该元素替换为空字符串(如果您愿意,也可以使用NA)。

+0

声明:我还没有在R中使用grep/regex功能,所以这可能不是最好的解决方案,但我只是把它扔在那里 - “ifelse()'已经在很多方面拯救了我的背后我已经失去了数量。 – 2012-03-09 21:21:57

+0

谢谢,在这种情况下,我没有考虑过ifelse(),但试图找出一种方法在您的答案后利用它。我很难从测试中捕获这种模式,而无需重复这个过程作为替换的一部分。我会再考虑一下。 – jed 2012-03-09 23:17:14