R子集数据集使用正则表达式

时间:2013-10-28 16:50:40

标签: regex r subset

有没有办法让下面的R代码运行得更快(即矢量化以避免使用for循环)?

我的示例包含两个数据框。首先是尺寸n1 * p。其中一列包含名称。第二数据帧是列向量(n2 * 1)。它也包含名称。我想保留第一个数据帧的所有行,其中第二个数据帧的列向量中的某些名称部分出现在相应的第一个数据帧中。对于残酷的解释感到抱歉。

示例(数据框1):

x        y 
Doggy    1 
Hello    2 
Hi Dog   3 
Zebra    4 

示例(数据框2)

z
Hello
Dog

所以在上面的例子中我想保留1,2,3行而不是4.因为“Dog”出现在“Doggy”和“Hi Dog”中。 “Hello”出现在“Hello”中。排除第四行,因为“Zebra”中没有出现“Hello”或“Dog”的部分。

下面是我执行此操作的R代码...运行正常。但是,对于我的真正任务。数据帧1有100万行,数据帧2有50个要匹配的项目。所以运行得很慢。关于如何提高速度的任何建议都表示赞赏。

x <- c("Doggy", "Hello", "Hi Dog", "Zebra")
y <- 1:4
dat <- as.data.frame(cbind(x,y))
names(dat) <- c("x","y")

z <- as.data.frame(c("Hello", "Dog"))
names(z) <- c("z")

dat$flag <- NA
for(j in 1:length(z$z)){
for(i in 1:dim(dat)[1]){ 

    if ( is.na(dat$flag[i])==TRUE ) {
        dat$flag[i] <- length(grep(paste(z[j,1]), dat[i,1], perl=TRUE, value=TRUE))
    } else {

    if (dat$flag[i]==0) {
        dat$flag[i] <- length(grep(paste(z[j,1]), dat[i,1], perl=TRUE, value=TRUE))

    } else { 

    if (dat$flag[i]==1) {
        dat$flag[i]==1
    }
    }
    }
}
}

dat1 <- subset(dat, flag==1)
dat1  

2 个答案:

答案 0 :(得分:7)

试试这个:

dat[grep(paste(z$z, collapse = "|"), dat$x), ]

subset(dat, grepl(paste(z$z, collapse = "|"), x))

答案 1 :(得分:1)

这个问题启发了qdap package中的布尔文本搜索功能(%bs%),因此我认为我可以分享这个问题的方法:

library(qdap)
dat[dat$x %bs% paste(z$z, collapse = "OR"), ]

在这种情况下,不少打字,但如果涉及多个或/和语句,这可能是一种有用的方法。