加速搜索元素

时间:2015-09-15 05:54:37

标签: r search

我有两个data.frames m(23列135.973行)和两个重要的列

head(m[,2])
# [1] "chr1" "chr1" "chr1" "chr1" "chr1" "chr1"
head(m[,7])
# [1] 3661216 3661217 3661223 3661224 3661564 3661567

search(4列1.019.423行),包含三个重要的列

head(search[,1])
# [1] "chr1" "chr1" "chr1" "chr1" "chr1" "chr1"
head(search[,3])
# [1] 3000009 3003160 3003187 3007262 3028947 3050944
head(search[,4])
# [1] 3000031 3003182 3003209 3007287 3028970 3050995

对于m中的每一行,如果m [XX,7]位置位于search [,3]和search的任何位置之间,我想获取信息[,4 ]。因此search [,3]可以被视为“开始”而search [,4]被视为“结束”。此外,search [,1]和m [,2]必须完全相同。

示例:

第215行

m “chr1”10.984.038 点击search第2898行 “chr1”10.984.024 10.984.046

一般来说,我不感兴趣的是哪一行或search可以找到多少行。我只想知道m中任何一行的信息是search是或否的匹配行。

我结束了这个功能:

f_4<-function(x,y,z){
    for (out in 1:length(x[,1])) {
        z[out]<-length(which((y[,1]==x[out,2]) &(x[out,7]>=y[,3]) &(x[out,7]<=y[,4])))
    }
    return(z)
}

found4<-vector(length=length(m[,1]), mode="numeric")
found4<-f_4(m,search,found4)

运行此代码需要3个小时。 我已经尝试了一些加速方法,但是我没有设法让这些运行正常或更快。

我甚至尝试了一些lappy / apply方法 - 虽然有效但速度不快 - 。但是,在尝试使用parLapply / parRapply加速时,他们失败了。

任何人都有一个更快的方法,可能会给出一些建议吗?

编辑2015/09/18 使用foreach %dopar%找到另一种加速方式。

    f5<-function(x,y,z){
          foreach(out=1:length(x[,1]), .combine="c") %dopar%  {
            takt<-1000
            z=length(which((y[,1]==x[out,2]) &(x[out,7]>=y[,3]) &(x[out,7]<=y[,4]) ))
          }   
          return(z)
        }

found5<-vector(length=length(m[,1]), mode="numeric")
found5<-f5(m,search,found5)

仅需45分钟。但是我总是只有0。我需要阅读更多foreach %dopar%教程。

2 个答案:

答案 0 :(得分:1)

您可以尝试与后续逻辑子集合并。首先,让我们创建一些模拟数据:

set.seed(123) # used for reproducibility
m <-as.data.frame(matrix(sample(50,7000, replace=T), ncol=7, nrow=1000))
search <- as.data.frame(matrix(sample(50,1200, replace=T), ncol=4, nrow=300))

由于我们要比较两组的不同行,我们可以使用m[,2]应该等于search[,1]的标准。为方便起见,我们可以命名这些列&#34; ID&#34;在两组中:

m <- cbind(m,seq_along(1:nrow(m)))
search <- cbind(search,seq_along(1:nrow(search)))
colnames(m) <- c("a","ID","c","d","e","f","val","rownum.m")
colnames(search) <- c("ID","nothing","start","end", "rownum.s")

我们在名为&#39; rownum.m&#39;的m中添加了一列。以及与search类似的列,最后将有助于识别初始数据集中的结果条目。

现在我们可以合并数据集,这样ID就是相同的:

m2 <- merge(m,search)

在最后一步中,我们可以执行合并数据集的逻辑子集,并将输出分配给新数据框m3

m3 <- m2[(m2[,"val"] >= m2[,"start"]) & (m2[,"val"] <= m2[,"end"]),]
#> head(m3)
#   ID  a  c  d  e  f val rownum.m nothing start end rownum.s
#5   1 14 36 36 31 30  25      846      10    20  36      291
#13  1 34 49 24  8 44  21      526      10    20  36      291
#17  1 19 32 29 44 24  35      522       6    33  48      265
#20  1 19 32 29 44 24  35      522      32    31  50       51
#21  1 19 32 29 44 24  35      522      10    20  36      291
#29  1  6 50 10 13 43  22       15      10    20  36      291

如果我们只对TRUE/FALSE语句感兴趣,m的特定行是否与标准匹配,我们可以定义向量match_s

match_s <- m$rownum.m %in% m3$rownum.m

可以存储为原始数据集m中的附加列:

m <- cbind(m,match_s)

最后,我们可以删除辅助列&#39; rownum.m&#39;来自m的不再需要的数据集m <- m[,-8]

结果是:

> head(m)
#   a ID  c  d  e  f val match_s
#1 15 14  8 11 16 13  23   FALSE
#2 40 30  8 48 42 50  20   FALSE
#3 21  9  8 19 30 36  19    TRUE
#4 45 43 26 32 41 33  27   FALSE
#5 48 43 25 10 15 13   4   FALSE
#6  3 24 31 33  8  5  36   FALSE

答案 1 :(得分:0)

如果您试图在一组基因组区域内找到SNP(例如),请不要使用R.使用BEDOPS

将您的SNP或单基地位置转换为三列BED文件。在R中,制作一个包含m[,2]m[,7]m[,7] + 1的三列数据表,它代表SNP的染色体,起始和终止位置。使用write.table()将此数据表写入制表符分隔的文本文件。

对您的基因组区域执行相同操作:将search[,1]search[,3]search[,4]写入表示该区域的染色体,起始和停止位置的三列数据表。使用write.table()将其写入制表符分隔的文本文件。

使用sort-bed to sort both BED files。此步骤可能是可选的,但它不需要很长时间,并且可以保证文件已准备好与BEDOPS工具一起使用。

最后,use bedmap on the two BED files to map SNPs to genomic regions。映射将SNP与区域相关联。 bedmap工具可以报告哪些SNP映射到某个区域,或报告SNP的数量,或者报告许多其他操作中的一个或多个。 bedmap的{​​{3}}详细介绍了操作列表,但documentation可以让您快速入门。

如果您的数据采用BED格式,或者可以快速强制转换为BED格式,请不要使用R进行基因组操作,因为它速度慢且占用大量内存。 BEDOPS工具包引入了使用排序来快速进行基因组操作,并且内存开销很低。