【发布时间】:2012-09-05 19:49:47
【问题描述】:
我想使用BiomaRt 包查询数据库。我有loci 并想检索一些相关信息,比如说description。
我第一次尝试使用lapply,但对执行任务所需的时间感到惊讶。因此我尝试了一个更基本的for-loop 并获得了更快的结果。
这是预期的还是我的代码或我对 apply 的理解有问题?我阅读了有关 *apply 与 for-loop 性能 (Here, for example) 的其他帖子,我知道不应期望性能提高,但我不明白为什么这里的性能实际上较低。
这是一个可重现的例子。
1) 加载库并选择数据库:
library("biomaRt")
athaliana <- useMart("plants_mart_14")
athaliana <- useDataset("athaliana_eg_gene",mart=athaliana)
2) 查询数据库:
loci <- c("at1g01300", "at1g01800", "at1g01900", "at1g02335", "at1g02790",
"at1g03220", "at1g03230", "at1g04040", "at1g04110", "at1g05240"
)
我创建了一个函数供lapply 使用:
foo <- function(loci) {
getBM("description","tair_locus",loci,athaliana)
}
当我在第一个元素上使用这个函数时:
> system.time(foo(cwp_loci[1]))
utilisateur système écoulé
0.020 0.004 1.599
当我使用lapply 检索所有值的数据时:
> system.time(lapply(loci, foo))
utilisateur système écoulé
0.220 0.000 16.376
然后我创建了一个新函数,添加了一个for-loop:
foo2 <- function(loci) {
for (i in loci) {
getBM("description","tair_locus",loci[i],athaliana)
}
}
结果如下:
> system.time(foo2(loci))
utilisateur système écoulé
0.204 0.004 10.919
当然,这将应用于loci 的大列表,因此需要性能最佳的选项。感谢您的帮助。
根据@MartinMorgan 的推荐编辑
简单地将向量loci传递给getBM,大大提高了查询效率。越简单越好。
> system.time(lapply(loci, foo))
utilisateur système écoulé
0.236 0.024 110.512
> system.time(foo2(loci))
utilisateur système écoulé
0.208 0.040 116.099
> system.time(foo(loci))
utilisateur système écoulé
0.028 0.000 6.193
【问题讨论】:
-
This 您可能感兴趣的问题。
-
@joran,但在这里它只是调用一个需要很长时间的函数,for 循环和 lapply 循环的次数相同。我不希望有什么不同。
-
@ptcoquin,如果您重复该过程 10 次,结果是否可重现?只是为了排除数据库的连接速度和业务是否起作用。一般来说,这类问题很难回答,因为您的示例涉及我们没有的数据库。
-
不仅仅是数据库访问,查询是基于网络的资源,因此人们会期望非常大的变化独立于任何 R 编码差异。此外,biomaRt 查询通常是矢量化的;此
getBM("description", "tair_locus", loci, athaliana)为您的 10 个基因座向量返回一个包含 10 个描述的向量。 -
@ptocquin 而不是使用 for 循环或 lapply,只需执行一个查询,
loci包含您想要的所有值。这会很快,因为只有一次通过 Internet 访问 biomaRt 服务器。