从范围中提取整数

dlv*_*dlv 11 integer r range

在R中,从范围中提取整数的有效方法是什么?

假设我有一个范围矩阵(column1 = start,column2 = end)

1   5
3   6
10  13
Run Code Online (Sandbox Code Playgroud)

我想将矩阵中所有范围的包含唯一整数存储到一个对象中:

1
2
3
4
5
6
10
11
12
13
Run Code Online (Sandbox Code Playgroud)

这将适用于包含约4百万个范围的矩阵,因此希望有人可以提供有效的解决方案.

Mar*_*gan 12

假设你有start = 3,end = 7,你在从1开始的数字行上标记为'1'

starts:     0 0 1 0 0 0 0 0 0 ...
ends + 1:   0 0 0 0 0 0 0 1 0 ...
Run Code Online (Sandbox Code Playgroud)

开始的累计总和减去两端的累积和,以及两者之间的差异

cumsum(starts):   0 0 1 1 1 1 1 1 1 ...
cumsum(ends + 1): 0 0 0 0 0 0 0 1 1 ...
diff:             0 0 1 1 1 1 1 0 0
Run Code Online (Sandbox Code Playgroud)

并且差异中的1的位置是

which(diff > 0): 3 4 5 6 7
Run Code Online (Sandbox Code Playgroud)

使用制表来允许在同一位置进行多次开始/结束,以及

range2 <- function(ranges)
{
    max <- max(ranges)
    starts <- tabulate(ranges[,1], max)
    ends <- tabulate(ranges[,2] + 1L, max)
    which(cumsum(starts) - cumsum(ends) > 0L)
}
Run Code Online (Sandbox Code Playgroud)

对于这个问题,这给出了

> eg <- matrix(c(1, 3, 10, 5, 6, 13), 3)
> range2(eg)
 [1]  1  2  3  4  5  6 10 11 12 13
Run Code Online (Sandbox Code Playgroud)

对于Andrie来说,这是非常快的

 > system.time(runs <- range2(xx))
   user  system elapsed 
  0.108   0.000   0.111 
Run Code Online (Sandbox Code Playgroud)

(这听起来有点像DNA序列分析,GenomicRanges可能是你的朋友;你可以使用coverageslice读取函数,也许输入readGappedAlignments).


sea*_*ody 5

我不知道它特别有效,但如果您的范围矩阵是ranges以下应该起作用:

unique(unlist(apply(ranges, 1, function(x) x[1]:x[2])))
Run Code Online (Sandbox Code Playgroud)


And*_*rie 5

使用sequencerep:

x <- matrix(c(1, 5, 3, 6, 10, 13), ncol=2, byrow=TRUE)

ranges <- function(x){
  len <- x[, 2] - x[, 1] + 1
  #allocate space
  a <- b <- vector("numeric", sum(len))
  a <- rep(x[, 1], len) 
  b <- sequence(len)-1
  unique(a+b)
}

ranges(x)
[1]  1  2  3  4  5  6 10 11 12 13
Run Code Online (Sandbox Code Playgroud)

由于这仅使用矢量化代码,因此即使对于大型数据集,这也应该非常快.在我的机器上,一百万行的输入矩阵需要大约5秒才能运行:

set.seed(1)
xx <- sample(1e6, 1e6)
xx <- matrix(c(xx, xx+sample(1:100, 1e6, replace=TRUE)), ncol=2)
str(xx)
 int [1:1000000, 1:2] 265509 372124 572853 908206 201682 898386 944670 660794 629110 61786 ...

system.time(zz <- ranges(xx))
user  system elapsed 
   4.33    0.78    5.22 

str(zz)
num [1:51470518] 265509 265510 265511 265512 265513 ...
Run Code Online (Sandbox Code Playgroud)