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

标签 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 的需求

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

最佳答案

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

这是一个 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

关于r - 从间隔列表中模拟随机位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49149839/

相关文章:

r - 柯尔莫哥洛夫-斯米尔诺夫检验

java - Java 版电梯模拟器帮助

r - R提取字符串的一部分

python - 下载多种生物的蛋白质序列

r - 在 ARIMA 或 VAR 模型中选择特定滞后

r - 通过R中的不同列值求和

routes - 使用 Omnet++ 模拟无线传感器网络中的地理路由

version-control - 鼓励非专业程序员的良好开发实践?

r - geom_text 没有标记闪避的 geom_bar

r - Shinydashboard 可以使用 Tabpanels 并具有导航栏吗?