封闭基因组数据的引导程序

时间:2017-06-24 15:00:23

标签: r bioinformatics genome

我正在尝试实施一个块引导程序,但我还没有找到一种有效的方法。

我的data.frame具有以下结构:

CHR POS var_A var_B
1 192 0,9 0,7
1 2000  0,8 0,3
2 3 0,21  0,76 
2 30009 0,36  0,15
...

第一列是染色体识别,第二列是位置,最后两列是我想要计算相关性的变量。问题是每一行并不是完全独立的,取决于它们之间的距离(越接近越依赖),所以我不能简单地做cor(df$var_A, df$var_B)

这种类型数据常用的问题是执行块引导程序。也就是说,我需要将数据划分为长度为X的块,随机选择该块内的一行,然后计算我感兴趣的统计量。但请注意,这些块需要根据列POS进行定义,而不是基于行号。此外,需要对每条染色体进行此程序。

我试图实现这一点,但我想出了最慢的代码(它甚至没有完成运行)并且我不是100%确定它是否有效。

x = 1000
cors = numeric()
iter = 1000
for(j in 1:iter) {
  df=freq[0,]
  for (i in unique(freq$CHR)) {
    t = freq[freq$CHR==i,]
    fim = t[nrow(t),2]
    i = t[1,2]
    f = i + x
    while(f < fim) {
      rows = which(t$POS>=i & t$POS<f)
      s = sample(rows)
      df = rbind(df,t[s,])
      i = f
      f = f + x
    }
  }
  cors = c(cors, cor(df$var_A, df$var_B))
}

有人可以帮帮我吗?我相信有一种更有效的方法。

提前谢谢。

3 个答案:

答案 0 :(得分:1)

我希望我理解你:

# needed for round_any()
library(plyr)

res <- lapply(unique(freq$CHR),function(x){

  freq_sel <- freq[freq$CHR==x,]
  blocks <- lapply(seq(1,round_any(max(freq_sel$POS),1000,ceiling),1000), function(ix) freq_sel[freq_sel$POS > ix & freq_sel$POS <= ix+999,])
  do.call(rbind,lapply(blocks,function(x) if (nrow(x) > 1) x[sample(1:nrow(x),1),] else x))

})

这应返回一个列表,其中包含每条染色体的条目。在每个条目中,如果存在,则每1kb块进行一次观察。块数由最大POS值确定。

编辑:

library(doParallel)
library(foreach)
library(plyr)

cl <-  makeCluster(detectCores())
registerDoParallel(cl)


res <- foreach(x=unique(freq$CHR),.packages = 'plyr') %dopar% {

  freq_sel <- freq[freq$CHR==x,]
  blocks <- lapply(seq(1,round_any(max(freq_sel$POS),1000,ceiling),1000), function(ix) freq_sel[freq_sel$POS > ix & freq_sel$POS <= ix+999,])
  do.call(rbind,lapply(blocks,function(x) if (nrow(x) > 1) x[sample(1:nrow(x),1),] else x))

}

stopCluster(cl)

这是每个染色体上foreach的简单并行化。重构函数并将并行处理基于另一个级别(例如1000次迭代或可能是块)可能更好。在任何情况下,我都可以再次强调我在评论中所说的内容:在您对代码进行并行化之前,您应该确保它尽可能高效。这意味着您可能需要查看boot包或类似内容以提高效率。也就是说,根据您计划的迭代次数,一旦您熟悉您的功能,并行处理可能会很有用。

答案 1 :(得分:1)

尝试的一种有效方法是使用'boot'包,其功能包括并行处理功能。

特别是,'tsboot'或时间序列引导功能将选择有序的数据块。如果您的POS变量是某种有序观察,这可能会有效。

启动包功能很棒,但首先需要一些帮助。要在引导包中使用引导函数,必须首先在包含index参数的函数中包装感兴趣的统计信息。这是bootstrap生成的索引将用于将采样数据传递给统计信息的设备。

cor_hat <- function(data, index) cor(y = data[index,]$var_A, x = data[index,]$var_B)

请注意以下参数中的cor_hatsim = "fixed", l = 1000个参数,表示您需要fixed个长度的块(l1000。但是,如果你试图捕捉随时间推移的最近邻居动态,你可以做任何大小的块,5或10。 multicore参数说明了一切,但如果您使用的是Windows,它可能会“下雪”。

library(boot)
tsboot(data, cor_hat, R = 1000, sim = "fixed", l = 1000, parallel = "multicore", ncpus = 4)

此外,统计学习要素的第194页提供了使用传统boot函数的框架的一个很好的例子,所有这些都与tsboot相关。 / p>

希望有所帮助,祝你好运。

贾斯汀

答案 2 :(得分:0)

所以,过了一会儿,我想出了一个问题的答案。在这里。

您需要包dplyr

l = 1000
teste = freq %>%
  mutate(w = ceiling(POS/l)) %>%
  group_by(CHR, w) %>%
  sample_n(1)

此代码根据基因组中的位置(POS)创建一个名为w的新变量。此变量w是指定每行的窗口,它取决于l,即窗口的长度。

您可以多次重复此代码,每次每个窗口采样一行/ CHR(使用sample_n(1))并应用您想要的任何感兴趣的统计数据。