Contents

## Warning: Package 'GGBase' is deprecated and will be removed from Bioconductor
##   version 3.13
## Warning: Package 'GGtools' is deprecated and will be removed from Bioconductor
##   version 3.13
## Warning: Package 'GGdata' is deprecated and will be removed from Bioconductor
##   version 3.13

R version: R version 4.0.3 (2020-10-10)

Bioconductor version: 3.12

Package: 1.14.0

1 Background

Numerous studies have employed genome-wide measures of mRNA abundance (typically assayed using DNA microarrays, and more recently RNA-seq) in combination with high-resolution genotyping (often supplemented with statistical imputation to loci not directly assayed, leading to genotype calls with quantified uncertainty) to search for genetic determinants of variation in gene expression. Key references in human applications include Cheung, Spielman, Ewens, Weber, Morley, and Burdick (2005), Majewski and Pastinen (2011), and Gaffney, Veyrieras, Degner, Pique-Regi, Pai, Crawford, Stephens, Gilad, and Pritchard (2012); Shabalin (2012) addresses computational concerns.

This document focuses on searches for eQTL in cis, so that DNA variants local to the gene assayed for expression are tested for association.

A typical report describes tuning of the search (including, for example, boundaries on minor allele frequencies of variants to be tested, approach to correction for batch effects and other forms of confounding, scope of search in terms of distance from gene coding region), enumerates variants with evidence of association to expression variation in nearby genes, and then characterizes the biological roles of the discovered variants.

N.B. The gQTLstats package will supersede GGtools for scalable eQTL analysis; look for a revised workflow 2016Q1.

2 Objectives

Suppose there are \(N\) independently sampled individuals with gene expression measures on \(G\) genes or probes. Each individual is genotyped (or has genotype statistically imputed) at \(S\) DNA locations, catalogued by NCBI dbSNP or 1000 genomes. We are given a \(G \times N\) matrix of expression assay results, and \(N \times S\) genotyping results in the form of the number of B alleles (or expected number of B alleles) for each of the loci. Select the search radius \(\rho\) (for example, 100kb) and for each gene \(g\), determine the search neighborhoods \(N_g = N_{g,\rho} = [a_g-\rho, b_g+\rho]\), where \(a_g\) denotes the genomic coordinate of the 5’ end of the transcript region for gene \(g\), and \(b_g\) is the coordinate at the 3’ end. Let \(|N_g|\) denote the number of SNP in that neighborhood. Key objectives are

2.1 Basic execution/reporting structure

The code in the example for the GGtools function All.cis() yields an example of a sharply restricted search for cis eQTL on chr21, using data on the HapMap CEU population.

## get data...build map...
## NOTE: expanding gene ranges by radius 25000 leads to negative start positions that are reset to 1.
## run smFilter...filter probes in map...tests...get data...build map...run smFilter...filter probes in map...tests...get data...build map...run smFilter...filter probes in map...tests...get data...build map...run smFilter...filter probes in map...tests...
cc = new("CisConfig") # take a default configuration
chrnames(cc) = "21"   # confine to chr21
estimates(cc) = FALSE # no point estimates neede
f1 <- All.cis( cc )   # compute the tests; can be slow without attendance
                      # to parallelization

The result of the function inherits from GRanges, and includes metadata concerning its generation.

length(f1)
## [1] 4038
f1[1:3]
## cisRun object with 3 ranges and 13 metadata columns:
##                 seqnames            ranges strand |         snp   snplocs
##                    <Rle>         <IRanges>  <Rle> | <character> <integer>
##   GI_11342663-S    chr21 41337026-41434392      + |    rs978935  41337036
##   GI_11342663-S    chr21 41337026-41434392      + |   rs2837335  41337988
##   GI_11342663-S    chr21 41337026-41434392      + |   rs2837336  41338014
##                     score       fdr       probeid       MAF  dist.mid   mindist
##                 <numeric> <numeric>   <character> <numeric> <numeric> <numeric>
##   GI_11342663-S      0.94         1 GI_11342663-S  0.316667    -48673     24990
##   GI_11342663-S      0.75         1 GI_11342663-S  0.320225    -47721     24038
##   GI_11342663-S      0.06         1 GI_11342663-S  0.366667    -47695     24012
##                 genestart   geneend permScore_1 permScore_2 permScore_3
##                 <integer> <integer>   <numeric>   <numeric>   <numeric>
##   GI_11342663-S  41362026  41409392        0.29        0.00        0.09
##   GI_11342663-S  41362026  41409392        0.30        0.03        0.03
##   GI_11342663-S  41362026  41409392        0.65        0.23        1.76
##   -------
##   seqinfo: 93 sequences (1 circular) from hg19 genome
metadata(f1)
## $call
## All.cis(config = cc)
## 
## $config
## CisConfig instance; genome  hg19 .  Key parameters:
## smpack =  GGdata ; chrnames =  21 
## nperm =  3 ; radius =  25000 
## ====
## Configure using 
##  [1] "smpack<-"        "rhs<-"           "nperm<-"         "folderStem<-"   
##  [5] "radius<-"        "shortfac<-"      "chrnames<-"      "smchrpref<-"    
##  [9] "gchrpref<-"      "schrpref<-"      "geneApply<-"     "geneannopk<-"   
## [13] "snpannopk<-"     "smFilter<-"      "exFilter<-"      "keepMapCache<-" 
## [17] "SSgen<-"         "genome<-"        "excludeRadius<-" "estimates<-"    
## [21] "extraProps<-"    "useME<-"         "MEpvot<-"

Use of GRanges for the organization of association test statistics allows easy amalgamation of findings with other forms of genomic annotation. Retention of the association scores achieved under permutation allows recomputation of plug-in FDR after combination or filtering.

2.2 Visualization examples

Targeted visualization of association is supported with the plot_EvG function in GGBase. To obtain the figure on the right, the expression matrix has been transformed by removing the principal components corresponding to the 10 largest eigenvalues. This is a crude approach to reducing ``expression heterogeneity’’, a main concern of eQTL analyses to date (Leek and Storey, 2007).

plot_EvG(probeId("o67h4JQSuEa02CJJIQ"), rsid("rs2259928"), c20f,
  main="10 expr. PC removed")

Above we have a single SNP-gene association.
The family of associations observed cis to ABHD12 can also be visualized in conjunction with the transcript models.

3 Raw materials: structuring expression, genotype, and sample data

3.1 SnpMatrix from snpStats for called and imputed genotypes

As of November 2013, a reasonably efficient representation of expression, sample and genotype data is defined using an R package containing

  • an ExpressionSet instance, and
  • a folder inst/parts containing genotype data as SnpMatrix instances, as defined in the snpStats package.

Elements of the sampleNames of the ExpressionSet instance must coincide with elements of the row names of the SnpMatrix instances. At time of analysis, warnings will be issued and harmonization attempts will be made when the coincidence is not exact.

The SnpMatrix instances make use of a byte code for (potentially) imputed genotypes. Each element of the code defines a point on the simplex displayed below, allowing a discrete but rich set of the key quantities of interest, the expected number of B alleles. Note that the nucleotide codes are not carried in this representation. Typically for a diallelic SNP, B denotes the alphabetically later nucleotide.

3.2 smlSet for coordinating genotype, expression, and sample-level data

We can illustrate the basic operations with this overall structure, using data collected on Yoruban (YRI) HapMap cell lines. Expression data were obtained at ArrayExpression E-MTAB-264 (Stranger, Montgomery, Dimas, Parts, Stegle, Ingle, Sekowska, Smith, Evans, Gutierrez-Arcelus, Price, Raj, Nisbett, Nica, Beazley, Durbin, Deloukas, and Dermitzakis, 2012).

library(GGtools)
library(yri1kgv)
library(lumiHumanAll.db)
if (!exists("y22")) y22 = getSS("yri1kgv", "chr22")
## harmonizeSamples TRUE and sampleNames for es not coincident with rownames(sml[[1]]); harmonizing...[not a warning]
y22
## SnpMatrix-based genotype set:
## number of samples:  79 
## number of chromosomes present:  1 
## annotation: lumiHumanAll.db 
## Expression data dims: 21800 x 79 
## Total number of SNP: 494322 
## Phenodata: An object of class 'AnnotatedDataFrame'
##   sampleNames: NA18486 NA18487 ... NA19257 (79 total)
##   varLabels: Source.Name Material.Type ... Factor.Value.SIGNAL. (26
##     total)
##   varMetadata: labelDescription
dim(exprs(y22))
## [1] 21800    79
fn = featureNames(y22)[1:5]

The annotation of expression features can be explored in several directions. First, the probe names themselves encode the 50mers on the chip.

library(lumi)
id2seq(fn) # get the 50mer for each probe
##                                   NQqs8dKRwVSgI4SRPk 
## "CAAGGGGTATTACTCAGGCACTAACCCCAGGAAAGATGACAGCACATTGC" 
##                                   BvIpQQ9yzp__kCLnEU 
## "GTTAGAGGCCAACAATTCTAGTATGGCTTGTTGGCAAAGAGTGCTACACC" 
##                                   NH1MoTHk7CULTog3nk 
## "ACTTCCATAGGACATACTGCATGTAAGCCAAGTCATGGAGAATCTGCTGC" 
##                                   KNJlVFShMX1UoyIkRc 
## "ATCAGCGCCCCCACCCAGGACATACCTTCCCCAGGATAGAGAGCACACCT" 
##                                   fuplG2R3erO3QrujDk 
## "GTGGGCGCCACGTCGCACTCTCTGGGTATGTCTCAAGGTGTGGATAATGC"
# and some annotation

Second, the mapping to institutionally curated gene identifiers is available.

select( lumiHumanAll.db, keys=fn, keytype="PROBEID", columns=c("SYMBOL", "CHR", "ENTREZID"))
## Warning in .deprecatedColsMessage(): Accessing gene location information via 'CHR','CHRLOC','CHRLOCEND' is
##   deprecated. Please use a range based accessor like genes(), or select()
##   with columns values like TXCHROM and TXSTART on a TxDb or OrganismDb
##   object instead.
## 'select()' returned 1:1 mapping between keys and columns
##              PROBEID       SYMBOL CHR  ENTREZID
## 1 NQqs8dKRwVSgI4SRPk        THBS3   1      7059
## 2 BvIpQQ9yzp__kCLnEU      SLC38A2  12     54407
## 3 NH1MoTHk7CULTog3nk        CCNB1   5       891
## 4 KNJlVFShMX1UoyIkRc       ZNF496   1     84838
## 5 fuplG2R3erO3QrujDk LOC100130238  12 100130238

Finally, we can look at the genotype information. This can be voluminous and is managed in an environment to reduce potential copying expenses.

gt22 <- smList(y22)[[1]]  # access to genotypes
as( gt22[1:5,1:5], "character" )
##         rs149201999 rs146752890 rs139377059 rs188945759 rs6518357
## NA18486 "A/A"       "A/A"       "A/A"       "A/A"       "A/A"    
## NA18487 "A/A"       "A/A"       "A/A"       "A/A"       "A/A"    
## NA18489 "A/A"       "A/A"       "A/A"       "A/A"       "A/A"    
## NA18498 "A/A"       "A/A"       "A/A"       "A/A"       "A/A"    
## NA18499 "A/A"       "A/A"       "A/A"       "A/A"       "A/A"
cs22 = col.summary(gt22)  # some information on genotypes
cs22[1:10,]
##             Calls Call.rate Certain.calls         RAF         MAF      P.AA
## rs149201999    79         1             1 0.094936709 0.094936709 0.8101266
## rs146752890    79         1             1 0.069620253 0.069620253 0.8607595
## rs139377059    79         1             1 0.069620253 0.069620253 0.8607595
## rs188945759    79         1             1 0.006329114 0.006329114 0.9873418
## rs6518357      79         1             1 0.075949367 0.075949367 0.8481013
## rs62224609     79         1             1 0.000000000 0.000000000 1.0000000
## rs62224610     79         1             1 0.297468354 0.297468354 0.4936709
## rs143503259    79         1             1 0.000000000 0.000000000 1.0000000
## rs192339082    79         1             1 0.000000000 0.000000000 1.0000000
## rs79725552     79         1             1 0.075949367 0.075949367 0.8481013
##                   P.AB       P.BB        z.HWE
## rs149201999 0.18987342 0.00000000  0.932328086
## rs146752890 0.13924051 0.00000000  0.665102984
## rs139377059 0.13924051 0.00000000  0.665102984
## rs188945759 0.01265823 0.00000000  0.056612703
## rs6518357   0.15189873 0.00000000  0.730536527
## rs62224609  0.00000000 0.00000000           NA
## rs62224610  0.41772152 0.08860759 -0.005111095
## rs143503259 0.00000000 0.00000000           NA
## rs192339082 0.00000000 0.00000000           NA
## rs79725552  0.15189873 0.00000000  0.730536527

4 Cluster management with starcluster

This workflow is based on Amazon EC2 computation managed using the MIT starcluster utilities. Configuration and management of EC2 based machinery is quite simple. The bulk of the partial run described here used configuration variables

In a complete run, for chromosome 1, a rescue run was required with a larger instance type (m3.2xlarge).

5 Programming the parallelized search: various approaches

5.1 High-level, socket-based cluster: ciseqByCluster

We will describe an essentially monolithic approach to using a cluster to search for eQTL in which evaluation of a single R function drives the search. The master process will communicate with slaves via sockets; slaves will write results to disk and ship back to master. The task is executed across chromosomes that have been split roughly in thirds to reduce RAM consumption.

The ciseqByCluster function of GGtools is the workhorse for the search. Arguments to this function determine how the search will be configured and executed. The invocation here asks for a search on four chromosomes, dispatching work from a master R process to a four node cluster, with multicore concurrency for gene-specific searches on eight cores per node. Three output files are generated in the folder identified as targetfolder:

  • an RDA file serializing a data.table instance with a record for each SNP-probe pair satisfying the cis proximity criterion
  • a tabix-indexed GFF3 file with the same information as the data.table
  • the tabix .tbi file for the GFF3

The following script is available on the AMI noted above and will generate the partceu100k_dt data.table instance used for analysis below.

library(parallel)
newcl = makePSOCKcluster(c("master", paste0("node00", 1:3)))
library(foreach)
library(doParallel)
registerDoParallel(cores=8)  # may want to keep at 5

library(GGtools)
ceuDemoRecov = try(ciseqByCluster( newcl, 
   chromsToRun=19:22, finaltag="partceu100k",
   outprefix="ceurun",
   ncoresPerNode=8, targetfolder="/freshdata/CEU_DEMO"  ))
save(ceuDemoRecov, file="ceuDemoRecov.rda")
stopCluster(newcl)
stopImplicitCluster()
sessionInfo()

The full set of arguments and defaults for ciseqByCluster is

  • pack = “yri1kgv”,
  • outprefix = “yrirun”,
  • chromsToRun = 1:22, # if length is C will use 3C nodes
  • targetfolder = “/freshdata/YRI_3”, # for demo, a volume reference
  • radius = 100000L,
  • nperm = 3L,
  • numNodes = 8,
  • nodeNames = rep(“localhost”, numNodes),
  • ncoresPerNode = 8,
  • numPCtoFilter = 10,
  • lowerMAF = .02,
  • geneannopk = “lumiHumanAll.db”,
  • snpannopk = “SNPlocs.Hsapiens.dbSNP144.GRCh37”
  • smchrpref = “chr”

The GFF3 file that is generated along with the data.table instance is useful for targeted queries, potentially from external applications. The primary difficulty with using this in R is the need to parse the optional data subfields of field 9.

6 Working with the results

6.1 Overview QQ-plot

It is customary to inspect QQ-plots for genome-wide association studies. For eQTL searches, the number of test results can range into the billions, so a binned approach is taken.

binnedQQ(partceu100k_dt, ylim=c(0,30), xlim=c(-2,15), end45=12)

This gives an indication that the distribution of the vast majority of observed SNP-gene pair association statistics is consistent with the null model.

6.3 Visualizing results for a gene

As of 1/20/2014 the call to scoresCis() can only be executed with R-devel and GGtools 4.11.28+.

We will focus on the data.table output. A basic objective is targeted visualization. The scoresCis function helps with this. We load the data.table instance first.

library(data.table)
data("partceu100k_dt.rda")
scoresCis("CPNE1", partceu100k_dt)

6.4 Statistical characteristics of search results

In this section we consider how structural and genetic information can be used to distinguish conditional probabilities of SNP genotypes being associated with phenotypic variation. We use some additional data provided in the GGtools package concerning a) chromatin state of the lymphoblastoid cell line GM12878, a line similar to those form which expression data were generated, and b) identities of SNP that have been found to be hits or are in LD with hits at $ R^2 > 0.80 $ in the NHGRI GWAS catalog. See man pages for hmm878 in GGtools package and gwastagger in gwascat package for more information. These data are automatically propagated to ciseqByCluster data.table output.

Our approach is to use logistic regression on 1.5 million records. We use the biglm package to keep memory images modest.

We discretize some of the key factors, and form an indicator variable for the event that the SNP is in a region of active or poised promoter chromatin state, as determined by ChromHMM on GM12878.

distcat = cut(partceu100k_dt$mindist,c(-1, 1, 1000, 5000, 10000, 50000, 100001))
fdrcat = cut(partceu100k_dt$fdr,c(-.01,.005, .05, .1, .2, 1.01))
fdrcat = relevel(fdrcat, "(0.2,1.01]")
mafcat = cut(partceu100k_dt$MAF,c(0,.05, .1, .2, .3, .51))
approm = 1*partceu100k_dt$chromcat878 %in% c("1_Active_Promoter", "3_Poised_Promoter")

Now we rebuild the data.table and fit the model to a randomly selected training set of about half the total number of records.

partceu100k_dt = cbind(partceu100k_dt, distcat, fdrcat, mafcat, approm)
set.seed(1234)
train = sample(1:nrow(partceu100k_dt), 
   size=floor(nrow(partceu100k_dt)/2), replace=FALSE)
library(biglm)
b1 = bigglm(isgwashit~distcat+fdrcat+mafcat+approm, fam=binomial(),
 data=partceu100k_dt[train,], maxit=30)

A source of figures of merit is the calibration of predictions against actual hit events in the test set.

pp = predict(b1, newdata=partceu100k_dt[-train,], type="response")
summary(pp)
##        V1          
##  Min.   :0.002191  
##  1st Qu.:0.006662  
##  Median :0.016831  
##  Mean   :0.015989  
##  3rd Qu.:0.027556  
##  Max.   :0.183083
cpp = cut(pp, c(0,.025, .05, .12, .21))
table(cpp)
## cpp
##    (0,0.025] (0.025,0.05]  (0.05,0.12]  (0.12,0.21] 
##      1032096       462408         1255         1630
sapply(split(partceu100k_dt$isgwashit[-train], cpp), mean)
##    (0,0.025] (0.025,0.05]  (0.05,0.12]  (0.12,0.21] 
##  0.009176472  0.030769364  0.079681275  0.136809816

It seems that the model, fit using data on a small number of chromosomes, has some predictive utility. We can visualize the coefficients:

tmat = matrix(rownames(summary(b1)$mat),nc=1)
est = summary(b1)$mat[,1]
library(rmeta)
forestplot(tmat, est, est-.01, est+.01, xlog=TRUE,
  boxsize=.35, graphwidth=unit(3, "inches"),
  xticks=exp(seq(-4,2,2)))

Standard errors in the presence of correlations among responses require further methodological development.

##            used  (Mb) gc trigger   (Mb)  max used   (Mb)
## Ncells 13712495 732.4   28481709 1521.1  28481709 1521.1
## Vcells 95548213 729.0  282636798 2156.4 431878141 3295.0

7 References

## Warning: Leek:2007p1723: unexpected END_OF_INPUT '
## '

[1] V. G. Cheung, R. S. Spielman, K. G. Ewens, et al. “Mapping determinants of human gene expression by regional and genome-wide association”. Eng. In: Nature 437.7063 (Oct. 2005), pp. 1365-9. DOI: 10.1038/nature04244.

[2] D. J. Gaffney, J. Veyrieras, J. F. Degner, et al. “Dissecting the regulatory architecture of gene expression QTLs”. Eng. In: Genome Biol 13.1 (Jan. 2012), p. R7. DOI: 10.1186/gb-2012-13-1-r7. <URL: http://genomebiology.com/content/13/1/R7>.

[3] J. T. Leek and J. D. Storey. “Capturing heterogeneity in gene expression studies by surrogate variable analysis”. Eng. In: PLoS Genet 3.9 (Sep. 2007), pp. 1724-35. DOI: 10.1371/journal.pgen.0030161. <URL: http://www.plosgenetics.org/article/info%253Adoi%252F10.1371%252Fjournal.pgen.0030161}.>

[4] J. Majewski and T. Pastinen. “The study of eQTL variations by RNA-seq: from SNPs to phenotypes”. Eng. In: Trends Genet 27.2 (Feb. 2011), pp. 72-9. DOI: 10.1016/j.tig.2010.10.006.

[5] A. A. Shabalin. “Matrix eQTL: ultra fast eQTL analysis via large matrix operations”. Eng. In: Bioinformatics (Oxford, England) 28.10 (May. 2012), pp. 1353-8. DOI: 10.1093/bioinformatics/bts163. <URL: http://bioinformatics.oxfordjournals.org/content/28/10/1353.long>.

[6] B. E. Stranger, S. B. Montgomery, A. S. Dimas, et al. “Patterns of cis regulatory variation in diverse human populations”. Eng. In: PLoS Genet 8.4 (Jan. 2012), p. e1002639. DOI: 10.1371/journal.pgen.1002639.

sessionInfo()
## R version 4.0.3 (2020-10-10)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 18.04.5 LTS
## 
## Matrix products: default
## BLAS:   /home/biocbuild/bbs-3.12-bioc/R/lib/libRblas.so
## LAPACK: /home/biocbuild/bbs-3.12-bioc/R/lib/libRlapack.so
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=C              
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
##  [1] grid      stats4    parallel  stats     graphics  grDevices utils    
##  [8] datasets  methods   base     
## 
## other attached packages:
##  [1] eQTL_1.14.0                             
##  [2] SNPlocs.Hsapiens.dbSNP144.GRCh37_0.99.20
##  [3] BSgenome_1.58.0                         
##  [4] rtracklayer_1.50.0                      
##  [5] Biostrings_2.58.0                       
##  [6] XVector_0.30.0                          
##  [7] rmeta_3.0                               
##  [8] lumiHumanAll.db_1.22.0                  
##  [9] biglm_0.9-2                             
## [10] DBI_1.1.0                               
## [11] doParallel_1.0.16                       
## [12] iterators_1.0.13                        
## [13] foreach_1.5.1                           
## [14] lumi_2.42.0                             
## [15] scatterplot3d_0.3-41                    
## [16] yri1kgv_0.32.0                          
## [17] GGdata_1.28.0                           
## [18] illuminaHumanv1.db_1.26.0               
## [19] GGtools_5.26.0                          
## [20] Homo.sapiens_1.3.1                      
## [21] TxDb.Hsapiens.UCSC.hg19.knownGene_3.2.2 
## [22] org.Hs.eg.db_3.12.0                     
## [23] GO.db_3.12.0                            
## [24] OrganismDbi_1.32.0                      
## [25] GenomicFeatures_1.42.0                  
## [26] GenomicRanges_1.42.0                    
## [27] AnnotationDbi_1.52.0                    
## [28] Biobase_2.50.0                          
## [29] data.table_1.13.2                       
## [30] GGBase_3.52.0                           
## [31] snpStats_1.40.0                         
## [32] Matrix_1.2-18                           
## [33] survival_3.2-7                          
## [34] GenomeInfoDb_1.26.0                     
## [35] IRanges_2.24.0                          
## [36] S4Vectors_0.28.0                        
## [37] BiocGenerics_0.36.0                     
## [38] bibtex_0.4.2.3                          
## [39] knitcitations_1.0.10                    
## [40] BiocStyle_2.18.0                        
## 
## loaded via a namespace (and not attached):
##   [1] tidyselect_1.1.0            RSQLite_2.2.1              
##   [3] htmlwidgets_1.5.2           BiocParallel_1.24.0        
##   [5] munsell_0.5.0               codetools_0.2-16           
##   [7] preprocessCore_1.52.0       nleqslv_3.3.2              
##   [9] colorspace_1.4-1            knitr_1.30                 
##  [11] rstudioapi_0.11             ROCR_1.0-11                
##  [13] MatrixGenerics_1.2.0        GenomeInfoDbData_1.2.4     
##  [15] bit64_4.0.5                 rhdf5_2.34.0               
##  [17] vctrs_0.3.4                 generics_0.0.2             
##  [19] xfun_0.18                   biovizBase_1.38.0          
##  [21] BiocFileCache_1.14.0        R6_2.5.0                   
##  [23] illuminaio_0.32.0           locfit_1.5-9.4             
##  [25] AnnotationFilter_1.14.0     bitops_1.0-6               
##  [27] rhdf5filters_1.2.0          reshape_0.8.8              
##  [29] DelayedArray_0.16.0         assertthat_0.2.1           
##  [31] scales_1.1.1                nnet_7.3-14                
##  [33] gtable_0.3.0                affy_1.68.0                
##  [35] methylumi_2.36.0            ensembldb_2.14.0           
##  [37] rlang_0.4.8                 genefilter_1.72.0          
##  [39] splines_4.0.3               lazyeval_0.2.2             
##  [41] GEOquery_2.58.0             dichromat_2.0-0            
##  [43] hexbin_1.28.1               checkmate_2.0.0            
##  [45] BiocManager_1.30.10         yaml_2.2.1                 
##  [47] reshape2_1.4.4              backports_1.1.10           
##  [49] Hmisc_4.4-1                 RBGL_1.66.0                
##  [51] tools_4.0.3                 bookdown_0.21              
##  [53] nor1mix_1.3-0               ggplot2_3.3.2              
##  [55] affyio_1.60.0               ellipsis_0.3.1             
##  [57] ff_4.0.4                    RColorBrewer_1.1-2         
##  [59] siggenes_1.64.0             Rcpp_1.0.5                 
##  [61] plyr_1.8.6                  base64enc_0.1-3            
##  [63] sparseMatrixStats_1.2.0     progress_1.2.2             
##  [65] zlibbioc_1.36.0             purrr_0.3.4                
##  [67] RCurl_1.98-1.2              prettyunits_1.1.1          
##  [69] rpart_4.1-15                openssl_1.4.3              
##  [71] bumphunter_1.32.0           SummarizedExperiment_1.20.0
##  [73] cluster_2.1.0               magrittr_1.5               
##  [75] magick_2.5.0                ProtGenerics_1.22.0        
##  [77] matrixStats_0.57.0          hms_0.5.3                  
##  [79] evaluate_0.14               xtable_1.8-4               
##  [81] XML_3.99-0.5                jpeg_0.1-8.1               
##  [83] mclust_5.4.6                gridExtra_2.3              
##  [85] compiler_4.0.3              biomaRt_2.46.0             
##  [87] minfi_1.36.0                tibble_3.0.4               
##  [89] KernSmooth_2.23-18          crayon_1.3.4               
##  [91] htmltools_0.5.0             mgcv_1.8-33                
##  [93] Formula_1.2-4               tidyr_1.1.2                
##  [95] lubridate_1.7.9             dbplyr_1.4.4               
##  [97] MASS_7.3-53                 rappdirs_0.3.1             
##  [99] readr_1.4.0                 quadprog_1.5-8             
## [101] Gviz_1.34.0                 pkgconfig_2.0.3            
## [103] GenomicAlignments_1.26.0    RefManageR_1.2.12          
## [105] foreign_0.8-80              xml2_1.3.2                 
## [107] annotate_1.68.0             rngtools_1.5               
## [109] multtest_2.46.0             beanplot_1.2               
## [111] doRNG_1.8.2                 scrime_1.3.5               
## [113] stringr_1.4.0               VariantAnnotation_1.36.0   
## [115] digest_0.6.27               graph_1.68.0               
## [117] rmarkdown_2.5               base64_2.0                 
## [119] htmlTable_2.1.0             DelayedMatrixStats_1.12.0  
## [121] curl_4.3                    Rsamtools_2.6.0            
## [123] nlme_3.1-150                lifecycle_0.2.0            
## [125] jsonlite_1.7.1              Rhdf5lib_1.12.0            
## [127] askpass_1.1                 limma_3.46.0               
## [129] pillar_1.4.6                lattice_0.20-41            
## [131] httr_1.4.2                  glue_1.4.2                 
## [133] png_0.1-7                   bit_4.0.4                  
## [135] stringi_1.5.3               HDF5Array_1.18.0           
## [137] blob_1.2.1                  latticeExtra_0.6-29        
## [139] memoise_1.1.0               dplyr_1.0.2