在R中加速大量GLM

时间:2012-03-11 23:44:55

标签: r optimization statistics glm

首先,对于长篇文章感到抱歉。认为最好给上下文以获得好的答案(我希望!)。前段时间我写了一个R函数,它将获得数据框中变量的所有成对交互。这在当时运作良好,但现在一位同事希望我用更大的数据集来做这件事。他们最终不知道他们将拥有多少变量,但他们猜测大约有2,500 - 3,000。我的下面的功能太慢了(100个变量4分钟)。在这篇文章的底部,我已经为不同数量的变量和交互总数包含了一些时间。我在我的函数的100个变量运行中调用Rprof()的结果,所以如果有人想看看它让我知道。我不想再超长时间了。

我想知道的是,我能做些什么来加快这个功能。我试着直接看看glm.fit,但据我所知,为了有用的设计矩阵的计算以及我坦率地不理解的所有其他东西,每个模型都需要相同,我的分析并非如此,尽管我可能错了。

任何有关如何使这种运行更快的想法将非常感激。我打算最后使用并行化来运行分析,但我不知道有多少CPU可以访问,但我会说它不会超过8个。

提前致谢, 干杯
戴维。

getInteractions2 = function(data, fSNPcol, ccCol)
{
#fSNPcol is the number of the column that contains the first SNP
#ccCol is the number of the column that contains the outcome variable
  require(lmtest)
  a = data.frame()
  snps =  names(data)[-1:-(fSNPcol-1)]
  names(data)[ccCol] = "PHENOTYPE"
  terms = as.data.frame(t(combn(snps,2)))
  attach(data)

  fit1 = c()
  fit2 = c()
  pval  = c()

  for(i in 1:length(terms$V1))
  {
    fit1 = glm(PHENOTYPE~get(as.character(terms$V1[i]))+get(as.character(terms$V2[i])),family="binomial")
    fit2 = glm(PHENOTYPE~get(as.character(terms$V1[i]))+get(as.character(terms$V2[i]))+I(get(as.character(terms$V1[i]))*get(as.character(terms$V2[i]))),family="binomial")
    a  = lrtest(fit1, fit2)
    pval = c(pval, a[2,"Pr(>Chisq)"])
  }

  detach(data)
  results = cbind(terms,pval) 
  return(results)
}

在下表中是system.time结果,用于增加通过函数传递的变量数量。 n是数字,而Ints是由该数量的变量给出的成​​对交互的数量。

      n   Ints     user.self sys.self elapsed
time  10   45      1.20     0.00    1.30
time  15  105      3.40     0.00    3.43
time  20  190      6.62     0.00    6.85
... 
time  90 4005    178.04     0.07  195.84
time  95 4465    199.97     0.13  218.30
time 100 4950    221.15     0.08  242.18

如果您想查看计时或Rprof()结果,可以重现数据框的某些代码。除非您的机器速度超快,或者您准备等待大约15-20分钟,否则请不要运行此操作。

df = data.frame(paste("sid",1:2000,sep=""),rbinom(2000,1,.5))
gtypes = matrix(nrow=2000, ncol=3000)
gtypes = apply(gtypes,2,function(x){x=sample(0:2, 2000, replace=T);x})
snps = paste("rs", 1000:3999,sep="")
df = cbind(df,gtypes)
names(df) = c("sid", "status", snps)

times = c()
for(i in seq(10,100, by=5)){
  if(i==100){Rprof()}
  time = system.time((pvals = getInteractions2(df[,1:i], 3, 2)))
  print(time)
  times = rbind(times, time)
  if(i==100){Rprof(NULL)}
}
numI = function(n){return(((n^2)-n)/2)}
timings = cbind(seq(10,100,by=5), sapply(seq(10,100,by=5), numI),times)

1 个答案:

答案 0 :(得分:0)

所以我有点解决了这个问题(在R邮件列表的帮助下),并且发布它,以防万一对任何人都有用。

基本上,在SNP或变量是独立的(即不在LD中,不相关),您可以将每个SNP /变量置于其中心,如下所示:

rs1cent <- rs1-mean(rs1)
rs2cent <- rs2 -mean(rs2)
然后,您可以测试表型和相互作用之间的相关性作为筛选步骤:

rs12interaction <- rs1cent*rs2cent
cor(PHENOTYPE, rs12interaction)

然后使用似乎相关的任何看起来完全调查完全glm。截止的选择一如既往地是随意的。

其他建议是使用RAO评分测试,其中仅涉及零假设模型,这使得此步骤的计算时间减半,但我真的不明白这是如何工作的(还需要更多阅读。)

无论如何你去了。也许有一天会对某人有用。