我有一组各种长度的DNA测序读数,按从长到短排序。我想知道我可以包含多少个读数在一个集合中,使得该集合的N50值高于某个阈值t。
对于任何给定的读数集合,总数据量就是读数长度的累积和。N50被定义为读数的长度,使得一半的数据包含在至少具有该长度的读数中。
我有一个解决方案如下,但对于非常大的读数集合来说速度较慢。我尝试将其向量化,但这更慢(可能是因为我的阈值通常相对较大,因此我的解决方案在计算到一定程度后会停止)。
以下是一个示例:
对于任何给定的读数集合,总数据量就是读数长度的累积和。N50被定义为读数的长度,使得一半的数据包含在至少具有该长度的读数中。
我有一个解决方案如下,但对于非常大的读数集合来说速度较慢。我尝试将其向量化,但这更慢(可能是因为我的阈值通常相对较大,因此我的解决方案在计算到一定程度后会停止)。
以下是一个示例:
df = data.frame(l = 100:1) # read lengths
df$cs = cumsum(df$l) # getting the cumulative sum is easy and quick
t = 95 # let's imagine that this is my threshold N50
for(i in 1:nrow(df)){
N50 = df$l[min(which(df$cs>df$cs[i]/2))]
if(N50 < t){ break }
}
# the loop will have gone one too far, so I subtract one
number.of.reads = as.integer(i-1)
这对小数据集没有问题,但我的实际数据更像是500万个读取结果,长度从约200,000到1不等(较长的读取结果较少),而我希望达到N50为100,000,那么速度就会变慢。
这个例子更接近于现实情况。在我的桌面上需要大约15秒。
l = ceiling(runif(100000, min = 0, max = 19999))
l = sort(l, decreasing = T)
df = data.frame(l = l)
df$cs = cumsum(df$l)
t = 18000
for(i in 1:nrow(df)){
n = df$l[min(which(df$cs>df$cs[i]/2))]
if(n < t){ break }
}
result = as.integer(i-1)
因此,我对任何能够显著优化这个问题的想法、技巧或窍门都感兴趣。看起来这应该是可能的,但是我已经没有任何想法了。