【问题标题】:R Subset Dataset Using Regular Expression使用正则表达式的 R 子集数据集
【发布时间】:2013-11-07 13:34:34
【问题描述】:

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

我的示例包含两个数据框。首先是维度 n1*p。 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”中。排除第 4 行,因为“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  

【问题讨论】:

    标签: regex r subset


    【解决方案1】:

    试试这个:

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

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

    【讨论】:

    • 非常感谢...对于真正的问题,旧的运行时间是 20 多分钟才中止。新的运行时间是
    【解决方案2】:

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

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

    在这种情况下,键入的次数也不少,但如果涉及多个 or/and 语句,这可能是一种有用的方法。

    【讨论】:

      猜你喜欢
      • 2014-01-04
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 2015-01-23
      • 2020-06-11
      • 2015-06-21
      • 1970-01-01
      • 2019-07-18
      相关资源
      最近更新 更多