代码之家  ›  专栏  ›  技术社区  ›  isthisthat

基于模式匹配的两个数据表的连接

  •  0
  • isthisthat  · 技术社区  · 1 年前

    鉴于

    library(data.table)
    dat1 <- setDT(data.frame(pat=c("A.C",".BC"),val=c(1,2)))
    dat2 <- setDT(data.frame(q=c("ABC","AXC","XBC"),val2=c(10,11,12)))
    

    我希望结果是:

    dat3 <- setDT(data.frame(pat=c("A.C","A.C",".BC",".BC"),val=c(1,1,2,2),q=c("ABC","AXC","ABC","XBC"),val2=c(10,11,10,12)))
    dat3
       pat val   q val2
    1: A.C   1 ABC   10
    2: A.C   1 AXC   11
    3: .BC   2 ABC   10
    4: .BC   2 XBC   12
    

    换句话说,的左联接 dat1 dat2 对于正则表达式模式的每个匹配 pat 查询字符串 q
    我想知道这是否可以用一个简洁的 data.table merge表达式,即。

    dat1[dat2, .(pat, val, q, val2), on= .(grepl(pat,q))] # this does not work
    

    或任何其他 数据表 提高效率的诀窍。事实上 dat1 是数百行和 dat2 可以是10-100000行。
    这听起来很简单,但我还没有找到一个完全涵盖它的帖子。

    我最接近的是以下内容:

    match_pat_to_q <- function(pattern, data, data.col="q"){
      ret<-lapply(pattern, function(x){
        data[grepl(x,get(data.col))]
      })
      names(ret) <- pattern # becomes an .id column in next step
      rbindlist(ret, idcol=TRUE)
    }
    
    match_pat_to_q(dat1$pat, dat2)[dat1, on=.(.id==pat)]
    
       .id   q val2 val
    1: A.C ABC   10   1
    2: A.C AXC   11   1
    3: .BC ABC   10   2
    4: .BC XBC   12   2
    
    1 回复  |  直到 1 年前
        1
  •  2
  •   B. Christian Kamgang    1 年前

    您可以按如下方式解决您的问题:

    dat1[, dat2[grep(pat, q), .(val, x=q, val2)], by=pat]
    
          pat   val      x  val2
       <char> <num> <char> <num>
    1:    A.C     1    ABC    10
    2:    A.C     1    AXC    11
    3:    .BC     2    ABC    10
    4:    .BC     2    XBC    12
    

    您所在的组 dat1 通过 pat 。这允许在逻辑上为中的每个模式创建一个组 dat1 。然后,对于每个组,您从中筛选相应的数据 dat2 使用模式匹配,同时选择所需的变量。