【问题标题】:Using data table to run 100,000 Fisher's Exact Tests is slower than apply使用数据表运行 100,000 次 Fisher 精确检验比应用慢
【发布时间】:2015-03-25 13:19:53
【问题描述】:

早上好,

我正在尝试使用 R 非常快速地运行 100,000 次 Fisher 对模拟遗传数据的精确测试,最好在 30 秒内(因为我需要置换病例对照标签并迭代该过程 1,000 次,因此它会运行一夜) .

我尝试在已融化、整齐的数据上使用数据表,其中包含大约 200,000,000 行和四列(受试者 ID、疾病状态、位置和“值”[野生型等位基因的数量,一个 3 因素变量]) .该函数按位置分组,然后针对疾病值执行 Fisher 精确检验。

> head(casecontrol3)
   ident disease position value
1:     1       0    36044     2
2:     2       0    36044     2
3:     3       0    36044     1
4:     4       0    36044     1
5:     5       0    36044     2
6:     6       0    36044     1

> setkey(casecontrol3,position)
> system.time(casecontrol4  <- casecontrol3[,list(p=fisher.test(value,
+     factor(disease))$p.value), by=position])
   user  system elapsed 
215.430  11.878 229.148

> head(casecontrol4)
   position            p
1:    36044 6.263228e-40
2:    36495 1.155289e-68
3:    38411 7.842216e-19
4:    41083 1.272841e-69
5:    41866 2.264452e-09
6:    41894 9.833324e-10

但是,与在扁平、凌乱的病例对照表(100,000 行;列包含信息:疾病状态和野生型等位基因的数量)上使用简单的应用函数相比,它确实很慢,所以首先应用函数将每一行转换为 2x3 案例控制表,并使用 Fisher 精确检验的矩阵语法)。将数据从以前的(未融化的)形式转换为这种形式(未显示)大约需要 20 秒的运行时间。

> head(cctab)
     control_aa control_aA control_AA case_aa case_aA case_AA
[1,]        291        501        208     521     432      47
[2,]        213        518        269      23     392     585
[3,]        170        499        331     215     628     157
[4,]        657        308         35     269     619     112
[5,]        439        463         98     348     597      55
[6,]        410        480        110     323     616      61

> myfisher <- function(row){
+     contab <- matrix(as.integer(row),nrow=2,byrow=TRUE)
+     pval <- fisher.test(contab)$p.value
+     return(pval)
+ }

> system.time(tab <- apply(cctab,1,"myfisher"))
   user  system elapsed 
 28.846  10.989  40.173

> head(tab)
[1] 6.263228e-40 1.155289e-68 7.842216e-19 1.272841e-69 2.264452e-09 9.833324e-10

如您所见,使用 apply 比使用 data.table 快得多,这真的让我感到惊讶。结果完全一样:

> identical(casecontrol4$p,tab)
[1] TRUE

有谁是使用 data.table 的专家,知道如何使用它来加快我的代码速度吗?还是数据太大了,我无法以融化的形式使用它(这排除了使用 data.table、dplyr 等)?请注意,我没有尝试过 dplyr,因为我听说 data.table 对于像这样的大数据集更快。

谢谢。

【问题讨论】:

  • 除了速度问题之外,我会与统计学家交谈,以确定运行 100K 测试是否合适而无需进行某种形式的更正。它为我敲响了各种各样的警钟。
  • 我不确定您的确切问题,但我在 R 中所做的是使用 R 分析器。它提取了一些堆栈样本,然后我在文本编辑器中手动查看这些样本。你不需要看很多样本。如果它花费了很大一部分时间,比如 50%,做一些可以避免的事情,那么这部分样本就会显示出来。
  • @thelatemail:稍后将进行多次测试更正(例如 Bonferroni)。
  • @AJP123:好的,你是说几乎所有的堆栈样本都包含fisher.test?然后我会做的是看看我是否需要 fisher.test 为我做的一切。它可能在一般性方面犯了错误 - 做的比我需要的多。然后我会看看是否有办法让它做到最低限度。最后,如果这还不够,我会考虑使用编译语言。每个人都希望 R 快,但它的主要目的不是快,而是易于使用。
  • @MikeDunlavey:是的 - 大多数堆栈样本都包含 fisher.test。我会和我的主管聊聊,如果我们需要它更快,我们可能会看看使用 Rcpp。

标签: r performance optimization time


【解决方案1】:

我会建议另一种方法 - 在您的方法中添加 HPC 元素。

您可以使用多个 CPU 或 GPU 内核、在 AWS EC2 上扩展一个免费的计算机集群、连接到 AWS EMR,或者使用众多出色的 HPC 工具来简化您现有的代码。

检查我们的CRAN HPC Task View 和这个tutorial

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2016-04-29
    相关资源
    最近更新 更多