从间隔列表中模拟随机位置

时间:2018-03-07 10:38:18

标签: r simulation bioinformatics bioconductor genomicranges

我正在尝试在R中开发一个函数来输出给定间隔列表中的随机位置。

我的间隔文件(14,600行)是制表符分隔的bed文件(chromosome start end name),如下所示:

1      4953    16204   1
1      16284   16612   1
1      16805   17086   1
1      18561   18757   1
1      18758   19040   1
1      19120   19445   1

目前,我的函数将在这些时间间隔内生成N个随机位置。

sim_dat <- bpSim(N=10)
head(sim_dat)
  seqnames    start      end width strand
1       1 22686939 22686939     1      *
2       1 14467770 14467770     1      *
3       2 10955472 10955472     1      *
4        X   823201   823201     1      *
5        6 10421738 10421738     1      *
6       17 21827745 21827745     1      *
library(GenomicRanges)
library(rtracklayer)

bpSim <- function(intervals="intervals.bed", N=100, write=F) {
  intFile <- import.bed(intervals)
  space <- sum(width(intFile))
  positions <- sample(c(1:space), N)
  cat("Simulating", N, "breakpoints", sep = " ", "\n")
  new_b <- GRanges(
    seqnames = as.character(rep(seqnames(intFile), width(intFile))),
    ranges = IRanges(start = unlist(mapply(seq, from = start(intFile), to = end(intFile))), width = 1)
  )
  bedOut <- new_b[positions]
  if (write) {
    export.bed(new_b[positions], "simulatedBPs.bed")
  }
  remove(new_b)
  return(data.frame(bedOut))
}

有效,但由于我对GenomicRanges软件包不是特别熟悉,所以我会将其归为一类。我更希望能够使用基础R或来自tidyverse的包来重写它,以便我可以调整它,例如,允许用户指定染色体。

这也需要很长时间 - 即使是N=10

system.time(sim_dat <- bpSim(N=10))
Simulating 10 breakpoints 
   user  system elapsed 
 10.689   3.267  13.970 

最终,我试图模拟基因组中的随机位置,因此需要为每个N模拟数百次数据。

我非常感谢任何关于如何做的建议:

  • 减少运行时间
  • 不再需要GenomicRanges

此外 - 如果有人知道任何已经执行此操作的软件包,我宁愿使用现有软件包而不是重新发明轮子。

1 个答案:

答案 0 :(得分:6)

对于范围不同的长度,我假设您希望这些随机选择的位置与段的长度成比例。换句话说,基于范围内的实际碱基对,选择是均匀的。否则,您将过度表示小范围(较高的标记密度)和不足的大范围(较低的标记密度)。

这是一个data.table解决方案,它可以立即完成一千个站点,并在我的机器上大约10秒内完成一百万个随机站点。它随机抽样您想要的站点数量,首先采样行(按每行的范围大小加权),然后在该范围内统一采样。

library(data.table)

nSites <- 1e4

bed <- data.table(chromosome=1, start=c(100,1050,3600,4000,9050), end=c(1000,3000,3700,8000,20000))

# calculate size of range
bed[, size := 1 + end-start]

# Randomly sample bed file rows, proportional to the length of each range
simulated.sites <- bed[sample(.N, size=nSites, replace=TRUE, prob=bed$size)]

# Randomly sample uniformly within each chosen range
simulated.sites[, position := sample(start:end, size=1), by=1:dim(simulated.sites)[1]]

# Remove extra columns and format as needed
simulated.sites[, start  := position]
simulated.sites[, end := position]
simulated.sites[, c("size", "position") := NULL]

这从表格开始,如:

 chromosome start   end  size
          1   100  1000   901
          1  1050  3000  1951
          1  3600  3700   101
          1  4000  8000  4001
          1  9050 20000 10951

输出如:

       chromosome start   end
    1:          1 10309 10309
    2:          1  4578  4578
    3:          1  1984  1984
    4:          1 14703 14703
    5:          1 10090 10090
   ---
 9996:          1  1601  1601
 9997:          1  5317  5317
 9998:          1 18918 18918
 9999:          1  1154  1154
10000:          1  7343  7343