【问题标题】:Vectorize data.table like, grepl, or similar for big data string comparisonVectorize data.table like, grepl, or similar to big data string comparison
【发布时间】:2016-06-10 04:47:04
【问题描述】:

我需要检查一列中的字符串是否包含来自另一列同一行的对应(数字)值,对于所有行。

如果我只检查单个模式的字符串,使用 data.table 的 likegrepl 将很简单。但是,每一行我的模式值都不同。

有一个有点相关的问题here,但与那个问题不同,我需要创建一个逻辑标志来指示模式是否存在。

假设这是我的数据集;

DT <- structure(list(category = c("administration", "nurse practitioner", 
                                  "trucking", "administration", "warehousing", "warehousing", "trucking", 
                                  "nurse practitioner", "nurse practitioner"), industry = c("admin", 
                                                                                            "truck", "truck", "admin", "nurse", "admin", "truck", "nurse", 
                                                                                            "truck")), .Names = c("category", "industry"), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                               -9L))
setDT(DT)
> DT
             category industry
1:     administration    admin
2: nurse practitioner    truck
3:           trucking    truck
4:     administration    admin
5:        warehousing    nurse
6:        warehousing    admin
7:           trucking    truck
8: nurse practitioner    nurse
9: nurse practitioner    truck

我想要的结果是这样的向量:

> DT
   matches
1: TRUE
2: FALSE
3: TRUE
4: TRUE
5: FALSE
6: FALSE
7: TRUE
8: TRUE
9: FALSE

当然,1 和 0 与 TRUE 和 FALSE 一样好。

以下是我尝试过的一些不起作用的方法:

apply(DT,1,grepl, pattern = DT[,2], x = DT[,1])
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

> apply(DT,1,grepl, pattern = DT[,1], x = DT[,2])
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

> grepl(DT[,2], DT[,1])
[1] FALSE

> DT[Vectorize(grepl)(industry, category, fixed = TRUE)]
             category industry
1:     administration    admin
2:           trucking    truck
3:     administration    admin
4:           trucking    truck
5: nurse practitioner    nurse

> DT[stringi::stri_detect_fixed(category, industry)]
             category industry
1:     administration    admin
2:           trucking    truck
3:     administration    admin
4:           trucking    truck
5: nurse practitioner    nurse

> for(i in 1:nrow(DT)){print(grepl(DT[i,2], DT[i,1]))}
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE

> for(i in 1:nrow(DT)){print(grepl(DT[i,2], DT[i,1], fixed = T))}
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE

> DT[category %like% industry]
         category industry
1: administration    admin
2: administration    admin
Warning message:
In grepl(pattern, vector) :
  argument 'pattern' has length > 1 and only the first element will be used

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    在 OP 的代码中,, 未被使用。因此,基于data.table 方法,它将子集对应于i 索引的行。

    但是,如果我们指定,,我们正在使用j,结果我们得到逻辑向量

    DT[, stri_detect_fixed(category, industry)]
    #[1]  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE
    

    假设,我们将它保存在list 中,然后我们得到一个带有列的data.table

    DT[, list(match=stri_detect_fixed(category, industry))]
    

    【讨论】:

    • @akrun 关于解决方案是正确的,Frank 对错误是正确的。非常感谢!
    • @Frank 谢谢,我更新了解决方案。如果有任何遗漏,请随时添加。
    【解决方案2】:

    或使用:

    apply(DT, 1, function(x) grepl(x[2], x[1],fixed=T))
    

    【讨论】:

    • 这也有效。这就是我在第一个示例中尝试做的事情。我想知道为什么我索引它的方式破坏了它。我猜行是由 apply() 中的边距暗示的。
    【解决方案3】:

    我通常这样做:

    DT[, flag := grepl(industry, category, fixed = TRUE), by = industry]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-03
      • 1970-01-01
      • 2022-12-28
      • 2019-11-11
      • 2016-02-15
      • 2021-07-07
      • 2015-03-21
      • 2016-10-27
      相关资源
      最近更新 更多