2012-08-01 33 views
2

我有一个向量,为此我想检查每个元素对数据帧的每一行。它涉及一个grep函数,因为要检查的元素被隐藏在其他文本中。检查数据帧的所有行的向量的每个元素

随着this forum帮助下,我得到这个代码:

mat=data.frame(par=c('long A story','C story', 'blabla D'),val=1:3) 
    vec=c('Z','D','A') 
    mat$label <- NA 
    for (x in vec){ 
     is.match <- lapply(mat$par,function(y) grep(x, y)) 
     mat$label[which(is.match > 0)] <- x 
    } 

的问题是,它需要几分钟来执行。有没有一种方法来对此进行矢量化?

回答

3

我以为你只需要在每一种情况下的第一场比赛:

which.matches <- grep("[ZDA]", mat$par) 
what.matches <- regmatches(mat$par, regexpr("[ZDA]", mat$par)) 

mat$label[which.matches] <- what.matches 
mat 

      par val label 
1 long A story 1  A 
2  C story 2 <NA> 
3  blabla D 3  D 

编辑:标杆

Unit: microseconds 
      expr  min  lq median  uq  max 
1 answer(mat) 185.338 194.0925 199.073 209.1850 898.919 
2 question(mat) 672.227 693.9610 708.601 725.6555 1457.046 

编辑2:

由于@mrdwab建议,这实际上可以作为单线使用:

mat$label[grep("[ZDA]", mat$par)] <- regmatches(mat$par, regexpr("[ZDA]", mat$par)) 
+0

我喜欢这样。如果你不想有太多的一次性使用对象(比如'which.matches'和'what.matches'),它甚至可以放在一行中。 – A5C1D2H2I1M1N2O1R2T1 2012-08-01 09:13:58

+0

嗯,你说得对。实际上并没有必要添加'mat $ label < - NA'。我会补充一点。 – 2012-08-01 09:16:23

+0

优秀!一个很大的改进。实际上,'vec'包含[多个]单词,所以表达式grep(“[ZDA]”变得凌乱。因此我有:expr = paste(vec,collapse ='|'); mat $ label [grep(expr ,mat $ $ par)] = regmatches(mat $ par,regexpr(expr,mat $ par)) – Henk 2012-08-01 11:17:48

相关问题