内容

1常见的Bioconductor工作流程

这个非常开放的主题指向一些最突出的Bioconductor包序列分析。利用这个实验的机会来探索下面突出显示的软件包小插图和帮助页面;欧洲杯2021体育彩票许多材料将在后续的实验和讲座中更详细地介绍。

特定于领域的分析——探索以下两个或三个包的登录页、小插图和参考手册。

工作序列,对齐,常见的web文件格式,和原始数据;这些包在很大程度上依赖于IRanges/GenomicRanges基础设施。

可视化

Alt测序生态系统

2计算:大数据

2.1非常高效。R代码

本节的目标是强调如何编写正确、健壮和高效的R代码。

2.2优先级

  1. 正确:与手工示例一致(相同的()all.equal ()
  2. 鲁棒性:支持真实输入,例如0长度向量,NA值,…
  3. 简单:简单易懂下个月;很容易描述它对同事的影响;容易发现逻辑错误;易于增强。
  4. 快,或者至少考虑到现代计算机的速度是合理的。

2.3策略

  1. 配置文件
    • 在脚本上理解它在做什么。
    • 一步通过代码看看它是如何执行的,并了解每一行的速度。
    • 时间计算选定的行或简单的代码块system.time ()或者是微基准测试包中。
    • 配置文件带有一个工具的代码,该工具指示在每个函数调用或行中花费了多少时间-内置的Rprof ()函数或包,例如lineprofaprof
  2. 向量化——操作向量,而不是显式循环

    x < - 1:10日志(x) # #不是(我在seq_along (x)) x[我]< -日志(x[我])
    ## [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379 1.9459101 2.0794415 2.1972246 ## [10] 2.3025851
  3. 预分配内存,然后填充结果

    Result <- numeric(10) Result [1] <- runif(1) for (i in 2:length(Result)) Result [i] <- runif(1) * Result [i - 1] Result
    ## [1] 0.331484123 0.272304255 0.073922382 0.059968133 0.045987249 0.020074915 0.007646036 0.004178788
  4. 将公共子表达式提升到重复计算之外,以便子表达式只计算一次
    • 简单,例如,从a中“提升”常数乘法循环
    • 更高级的,例如,使用lm.fit ()而不是重复拟合相同的设计矩阵。
  5. 重用现有的、经过测试的代码

2.3.1案例研究:预分配和向量化

这是一个明显低效的函数:

f0 < -函数(n = 2) {# # stopifnot (is.integer (n) & &(长度(n) = = 1) & & # # ! is.na (n) & & (n > 0))结果< -数字()(我在seq_len (n))结果[[我]]< - *日志(i)结果}

使用system.time ()研究这个算法是如何扩展的n,重点关注经过的时间。

system.time (f0 (10000))
##用户系统运行## 0.187 0.008 0.195
n < - 1000 * seq(2) 1, 20日t < -酸式焦磷酸钠(n,函数(i) system.time (f0(我)[[3]])情节(t ~ n、类型=“b”)

记住当前的“正确”值和一个大概的时间

N <- 10000系统。时间(期望<- f0(n))
##用户系统运行时间## 0.179 0.000 0.179
(预计)
## [1] 0.000000 1.386294 2.197225 2.772589 3.218876 3.583519

修改功能提升普通乘数,一个在这个圈子之外。确保“优化”的结果与原始计算相同。使用微基准测试包来比较两个版本

F1 <- function(n, a=2) {result <- numeric() for (i in seq_len(n)) result[[i]] <- log(i) a * result}相同(期望,F1 (n))
##[1]真
库(微基准)微基准(f0(n), f1(n), times=5)
##单位:毫秒## expr min lq mean median uq max neval ## f0(n) 156.3378 156.4045 175.3319 156.8620 203.4312 203.6239 5 ## f1(n) 155.3136 156.5851 265.3980 202.0044 202.1739 610.9129

采用“预分配和填充”策略

F2 <- function(n, a=2) {result <- numeric(n) for (i in seq_len(n)) result[[i]] <- log(i) a * result}相同(预期,F2 (n))
##[1]真
微基准测试(f0(n), f2(n), times=5)
##单位:毫秒## expr min lq mean median uq max neval ## f0(n) 155.993159 156.635264 175.518239 157.970451 203.158903 203.833420 5 ## f2(n) 7.922534 7.930492 7.951939 7.954765 7.961272 7.990633 5

使用一个*应用()函数,以避免必须显式预分配,并使向量化的机会更加明显。

F3 <-函数(n, a=2) a * sapply(seq_len(n), log)相同(预期,F3 (n))
##[1]真
微基准测试(f0(n), f2(n), f3(n), times=10)
##单位:毫秒## expr min lq mean median uq max neval ## f0(n) 155.782877 155.912423 179.260635 179.434312 202.485429 202.642872 10 ## f2(n) 7.899218 7.910416 8.441093 7.980780 8.133669 10.315199 10 ## f3(n) 3.762718 3.806632 3.836373 3.849915 3.862659 3.880582 10

现在代码以单行形式呈现,显然可以很容易地向量化。抓住机会将其向量化:

F4 <-函数(n, a=2) a * log(seq_len(n))相同(预期,F4 (n))
##[1]真
微基准(f0(n), f3(n), f4(n), times=10)
##单位:微秒## expr min lq mean median uq max neval ## f0(n) 155763.460 155858.448 179344.1292 179768.8200 202611.040 202708.645 10 ## f3(n) 3773.596 3794.231 3907.6489 3848.1350 3865.203 4611.464 10 ## f4(n) 366.626 367.884 373.7918 373.7705 376.339 385.529 10

f4 ()看起来绝对是赢家。它是如何扩展的n?(重复几次)

N <- 10 ^ (5:8) # 100x大于f0 t <- sapply(N, function(i) system.time(f4(i))[[3]]) plot(t ~ N, log="xy", type="b")

对不同的反应模式有什么解释吗?

经验教训:

  1. 与迭代相比,向量化提供了巨大的改进
  2. 当需要显式迭代时,预分配和填充非常有用。
  3. *应用()函数有助于避免显式预分配的需要,并使向量化的机会更加明显。这可能会带来很小的性能成本,但通常是值得的
  4. 当需要显式迭代时,提升公共子表达式有助于提高性能。

2.4平行的评价

当数据太大而无法装入内存时,我们可以以块的形式遍历文件,或者按字段或基因组位置对数据进行子集。

迭代

限制

平行进行

BiocParallel为简单的并行计算提供标准化接口。包构建提供了对多核的功能平行包装以及BatchJobs用于运行集群作业。

一般的想法:

2.4.1练习:连续和平行睡觉

这个小示例激发了并行执行的使用,并演示了如何使用bplapply ()可以顺便去看看吗拉普兰人

使用system.time ()来探索这需要多长时间来执行n从1增加到10。使用相同的()微基准测试比较不同的选择f0 ()f1 ()为了正确性和性能。

有趣的休眠1秒,然后返回

library(BiocParallel) fun <- function(i) {Sys.sleep(1) i} ## serial f0 <- function(n) lapply(seq_len(n), fun) ## parallel f1 <- function(n) bplapply(seq_len(n), fun)