找到两个数字列表的模式,并在r中使用更好的解决方案

时间:2013-11-06 20:02:14

标签: r

我正在研究这个问题,但对我的解决方案并不是很满意。在较大的文件上效率不高。

我有两个数字列表:

a <- as.numeric(c("12345678","2235689","56980"))
b <- as.numeric(c("123","1234","223","2235689","111","222","555","888","12345","8989"))

我需要知道来自START的任何数字是否包含b中的任何数字。

所以我写了一个函数如下:

findpattern <- function(a,b){
  a_s<-c()
  b_s<-c()
  for (a1 in a){
    z<-sapply(b,function(x)(1 %in% (regexpr(x,a1))))
    if (TRUE %in% unique(z)){
      b1 <- b[z]
      a_s<- c(a_s,a1)
      b_s<- c(b_s,pplist(b1))
    }
  }
  res <- data.frame(a_find=a_s,b_associate=b_s)
  return (res)
}

所以结果应该是:

> findpattern(a,b)
   a_find    b_associate
1 12345678 123,1234,12345
2  2235689    223,2235689

但是我对我的解决方案不满意,因为当b文件带有超过10k的数字时,它需要相当长的时间来完成它...有更好的解决方案吗?

非常感谢!!!!

1 个答案:

答案 0 :(得分:4)

也许你想要这样的东西?

result <- sapply(paste0('^', b), grepl, x=a)
rownames(result) <- a
#           ^123 ^1234  ^223 ^2235689  ^111  ^222  ^555  ^888 ^12345 ^8989
# 12345678  TRUE  TRUE FALSE    FALSE FALSE FALSE FALSE FALSE   TRUE FALSE
# 2235689  FALSE FALSE  TRUE     TRUE FALSE FALSE FALSE FALSE  FALSE FALSE
# 56980    FALSE FALSE FALSE    FALSE FALSE FALSE FALSE FALSE  FALSE FALSE

要以与示例结果类似的格式获取此内容:

result.l <- apply(result, 1, function(row) b[row])
# $`12345678`
# [1]   123  1234 12345
# 
# $`2235689`
# [1]     223 2235689
# 
# $`56980`
# numeric(0)

我建议使用您在问题中显示的格式,这是非标准格式。

或者这看起来像你想要的结果,但是有一个标准的结构。

stack(lapply(result.l, paste, collapse=','))
#           values      ind
# 1 123,1234,12345 12345678
# 2    223,2235689  2235689
# 3                   56980