【问题标题】:How to efficiently count matches across a list in R?如何有效地计算 R 中列表中的匹配项?
【发布时间】:2019-12-04 02:19:53
【问题描述】:

我有一个整数向量列表,例如:

set.seed(1)

vec_list <- replicate(100, sample(1:10000000, size=sample(1:10000, 100)), simplify=FALSE)

还有一个整数向量,例如:

vec <- sample(1:10000000, size=10000)

如何计算 vec_list 中每个向量中出现在向量 vec 中的整数的数量?我可以使用 for 循环来做到这一点。例如:

total_match <- rep(NA, length(vec_list))

for (i in 1:length(vec_list)){
  total_match[i] <- length(which(vec_list[[i]] %in% vec))
  print(i)
}

但是,我尝试应用的列表和向量也非常大,而且速度很慢。请提供有关如何提高性能的建议。

使用 data.table 更快,但在没有匹配项时不会返回 0。例如:

DT <- data.table(repid=rep(1:length(vec_list), sapply(vec_list, length)), val=unlist(vec_list))
total_match2 <- DT[.(vec), on=.(val), nomatch=0L, .N, keyby=.(repid)]$N

【问题讨论】:

    标签: r list performance data.table match


    【解决方案1】:

    另一个,@chinsoon 的变体:

    nvec = 5000
    max_size = 10000
    nv = 10000000
    
    set.seed(1)
    vec_list <- replicate(nvec, sample(nv, size=sample(max_size, 1)), simplify=FALSE)
    vec <- sample(nv, size=max_size)
    
    system.time(
      res <- rbindlist(lapply(vec_list, list), id=TRUE)[.(vec), on=.(V1), nomatch=0, .N, keyby=.id]
    )
    #    user  system elapsed 
    #    0.86    0.20    0.47 
    
    
    system.time({
      DT <- setDT(stack(setNames(vec_list, 1:length(vec_list))))
      res2 <- DT[, x := +(values %in% vec)][, sum(x), keyby=.(ind)]$V1
    })
    #    user  system elapsed 
    #    1.03    0.45    1.00 
    
    
    identical(res2[res2 != 0], res$N) # TRUE
    

    【讨论】:

    • 也许添加 [ .(ID=seq_len(nvec)), on=.(ID)][is.na(N), N := 0L] 以完成没有匹配项的列表
    【解决方案2】:

    不妨试试:

    DT <- setDT(stack(setNames(vec_list, 1:length(vec_list))))
    DT[, x := +(values %in% vec)][, sum(x), keyby=.(ind)]$V1
    

    【讨论】:

    • Rcpp 版本可能更快,但在您的代码的后续部分中,您最好还是使用 data.table,而不是用 C/C++ 编写所有代码
    【解决方案3】:

    怎么样:

    sapply(vec_list, function(x) sum(x %in% vec))
    

    【讨论】:

      猜你喜欢
      • 2011-10-07
      • 2016-05-06
      • 2019-02-11
      • 2022-07-06
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      相关资源
      最近更新 更多