优化 data.table 上的 row-wise 函数

问题描述 投票:0回答:1

我很难为数字范围上的键连接创建快速的 data.table 解决方案。我有以下输入数据:

coverageTable <- data.table('position' = c(1:6),
                            'coverage' = c(15, 5, 20, 15, 9, 11))
variantMatrix <- data.table('start' = c(1,2,3,5),
                            'end' = c(1,2,4,6))

我想向variantMatrix返回一个名为covered_alleles的列,如果variantMatrix的start:end中的所有位置都被覆盖> = 10(取自coverageTable中的coverage列),则该列的值为2,如果不满足此条件,则返回值为0 .

目前,我正在使用以下代码,该代码可以工作,但速度很慢:

isCovered <- function( coverageTable, start, end ) {

   return(ifelse(all(coverageTable[.(start:end),coverage]>=10),2,0))

}

setkey(coverageTable,position)
variantMatrix[,covered_alleles:=isCovered(coverageTable,start,end),by=c('start','end')]

我的预期输出是:

       start   end covered_alleles
   <num> <num>           <num>
1:     1     1               2
2:     2     2               0
3:     3     4               2
4:     5     6               0

但是,我需要在数百万个变体上运行此代码,因此将此函数逐行应用于variantMatrix 的速度非常慢。有没有办法使用 data.table 语法来使此操作更快?谢谢!

r optimization data.table
1个回答
0
投票

我建议对

coverageTable
进行基于范围的联接,以确定每个
variantMatrix
行属于哪一行,然后根据值汇总这些行。

## "unique id" for each row
variantMatrix[, rn := .I]
coverageTable[variantMatrix, rn := i.rn,
              on = .(position >= start, position <= end)]
#    position coverage    rn
#       <int>    <num> <int>
# 1:        1       15     1
# 2:        2        5     2
# 3:        3       20     3
# 4:        4       15     3
# 5:        5        9     4
# 6:        6       11     4

最后,

variantMatrix[
  coverageTable[, .(covered_alleles = fifelse(all(coverage >= 10), 2L, 0L)), by = "rn"],
  on = "rn"]
#    start   end    rn covered_alleles
#    <num> <num> <int>           <int>
# 1:     1     1     1               2
# 2:     2     2     2               0
# 3:     3     4     3               2
# 4:     5     6     4               0

这样做的副作用是

coverageTable$rn
存在,很容易清理。

© www.soinside.com 2019 - 2024. All rights reserved.