バイオインフォ独学中

独学でNGS解析やR言語を勉強してます。忘備録として記録に残そうと思います。

R/Bioconductorでマイクロアレイ解析

大学で今日やったハンズオン講習会は学内環境の問題で上手く行かなかった。勿体無いので資料を公開します。 もっとこうした方が良いとか、ここが間違っているとかあったら是非コメントしてください。 初投稿なので勝手が分からない...

Microarray analysis ~Is microarray analysis outdated?~

Let’s analyse microarray with R/Bioconductor. Compared with RNA-seq, microarray requires less CPU and memory consumption. We no longer need to pay for expensive softwares such as GeneSpring to get gene expression data and conduct differential gene expression analysis. R/Bioconductor is an open-source and freely available repository for bioinformatics. You can almost do anything you want with R/Bioconductor.

I used the workflow below as reference http://bioconductor.org/packages/release/workflows/html/maEndToEnd.html.

FYI, the latest version of Bioconductor 3.10 is now availablehttps://www.bioconductor.org.

    # 20191102 handson trainning for microarray analysis at YCU, Fuku-ura
    # Affymetrics microarray
    # download and read CEL files, RMA normalisation, quality check (PCA, clustering and so on), DEA, visualisation such as MA plot, volcano plot and heatmap.

    # about the data
    # WT and Bcl6 cKO (probably Itgax-cre) mice splenic DCs(cDC1, cDC2, pDC)
    # Kenneth Murphy's lab, unpublished data
    # we are going to compare WT vs Bcl6cKO cDC1 this time
    # accession number is GSE135904 https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE135904
    # platform [MoGene-1_0-st] Affymetrix Mouse Gene 1.0 ST Array [transcript (gene) version]

    ##############
    # install and load required packages
    library(BiocManager)
    # BiocManager::install(c("mogene10sttranscriptcluster.db", "pd.mogene.1.0.st.v1", GEOquery"))
    library(GEOquery)
    library(mogene10sttranscriptcluster.db)
    library(pd.mogene.1.0.st.v1)
    library(oligo)
    library(limma)
    # general packeges
    # install.packages()
    library(tidyverse)
    library(gplots)
    library(ggrepel)
    library(viridis)
    library(RColorBrewer)
    ############### 
    # download the raw data from GEO
    # download manually from https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE135904
    # or
    # automatically download
    # using GEOquery package
    # getGEOSuppFiles('GSE135904', fetch_files = TRUE) # download 
    list.files("GSE135904/GSE135904_RAW/")
##  [1] "GSM4037643_WT_cDC1_rep1.CEL.gz"  "GSM4037644_WT_cDC1_rep2.CEL.gz" 
##  [3] "GSM4037645_WT_cDC1_rep3.CEL.gz"  "GSM4037646_cKO_cDC1_rep1.CEL.gz"
##  [5] "GSM4037647_cKO_cDC1_rep2.CEL.gz" "GSM4037648_cKO_cDC1_rep3.CEL.gz"
##  [7] "GSM4037649_cKO_cDC1_rep4.CEL.gz" "GSM4037650_WT_cDC2_rep1.CEL.gz" 
##  [9] "GSM4037651_WT_cDC2_rep2.CEL.gz"  "GSM4037652_WT_cDC2_rep3.CEL.gz" 
## [11] "GSM4037653_cKO_cDC2_rep1.CEL.gz" "GSM4037654_cKO_cDC2_rep2.CEL.gz"
## [13] "GSM4037655_cKO_cDC2_rep3.CEL.gz" "GSM4037656_cKO_cDC2_rep4.CEL.gz"
## [15] "GSM4037657_cKO_cDC2_rep5.CEL.gz" "GSM4037658_WT_pDC_rep1.CEL.gz"  
## [17] "GSM4037659_WT_pDC_rep2.CEL.gz"   "GSM4037660_WT_pDC_rep3.CEL.gz"  
## [19] "GSM4037661_cKO_pDC_rep1.CEL.gz"  "GSM4037662_cKO_pDC_rep2.CEL.gz" 
## [21] "GSM4037663_cKO_pDC_rep3.CEL.gz"  "GSM4037664_cKO_pDC_rep4.CEL.gz" 
## [23] "GSM4037665_cKO_pDC_rep5.CEL.gz"
    # read CEL files
    # extract only cDC1 data
    celFiles <- list.celfiles("GSE135904/GSE135904_RAW/", listGzipped = T, full.names = TRUE)
    celFiles2 <- celFiles %>% str_subset(pattern = "cDC1") # extract which contains "cDC1" in its name
    affyRaw <- oligo::read.celfiles(celFiles2) # reading CEL files
## Platform design info loaded.

## Reading in : GSE135904/GSE135904_RAW//GSM4037643_WT_cDC1_rep1.CEL.gz
## Reading in : GSE135904/GSE135904_RAW//GSM4037644_WT_cDC1_rep2.CEL.gz
## Reading in : GSE135904/GSE135904_RAW//GSM4037645_WT_cDC1_rep3.CEL.gz
## Reading in : GSE135904/GSE135904_RAW//GSM4037646_cKO_cDC1_rep1.CEL.gz
## Reading in : GSE135904/GSE135904_RAW//GSM4037647_cKO_cDC1_rep2.CEL.gz
## Reading in : GSE135904/GSE135904_RAW//GSM4037648_cKO_cDC1_rep3.CEL.gz
## Reading in : GSE135904/GSE135904_RAW//GSM4037649_cKO_cDC1_rep4.CEL.gz
    # next step is normalisation
    # RMA - Robust Multichip Average algorithm
    # Robust Multichip Average preprocessing methodology. 
    # This strategy allows background subtraction, quantile normalization and summarization (via median-polish).
    # RMA method is now the most popular normalisation methods for Affymetrics microarray. There are other methods like MAS5 and gcrma.
    eset <- oligo::rma(affyRaw) # RMA
## Background correcting
## Normalizing
## Calculating Expression
    #################### 
    # quality check
    # boxplot
    par(mfrow = c(1,2)) # separate plot panel
    oligo::boxplot(affyRaw, target = "core", las = 3, main = "raw data") # before RMA
    oligo::boxplot(eset, las = 3, main = "normalised data (RMA method)") # after RMA

boxplot

    # density plot
    oligo::hist(affyRaw, target = "core", main = "raw data")

density_raw

    oligo::hist(eset, main = "normalised data (RMA method)")

density_rma

    # output an expression matrix
    Biobase::write.exprs(eset, file = "cDC1_gene_expression.txt")

    # change column names for simplicity
    cDC1_gene_expression <- Biobase::exprs(eset)
    colnames(cDC1_gene_expression) <- c("WT_1", "WT_2", "WT_3", "cKO_1", "cKO_2", "cKO_3", "cKO_4")

    # perform hierarchical clustering
    # several methods
    dist <- as.dist(1 - cor(cDC1_gene_expression, method = "pearson")) # calculate Pearson's distance
    cluster_ward <- hclust(dist, method = "ward.D2") # ward method
    cluster_ave <- hclust(dist, method = "average") #  group average method
    # par(mfrow = c(1,2))
    plot(cluster_ward, main = "ward", hang = -1)

hc_dendro_ward

    plot(cluster_ave, main = "average", hang = -1) # any differences b/w these?

hc_dendr_averge

    # PCA principal component analysis
    # R uses `prcomp` function for PCA
    # generally speaking, an expression matrix has genes in its rows and samples in columns
    # so we need to transpose rows and columns
    # by using t() function in R
    PCA <- prcomp(t(cDC1_gene_expression), scale = FALSE) # data already normalised so that "scale = FALSE"
    percentVar <- round(100*PCA$sdev^2/sum(PCA$sdev^2),1) # calculate stats, these codes copied from somewhere on the Internet
    sd_ratio <- sqrt(percentVar[2] / percentVar[1])
    is(PCA)
## [1] "prcomp"
    is(PCA$x[, 1:2])
## [1] "matrix"           "array"            "mMatrix"         
## [4] "ff_or_matrix"     "structure"        "vector"          
## [7] "vector_OR_factor"
    PCA.df <- PCA$x[, 1:2] # get PC1 and PC2
    PCA.df
##              PC1        PC2
## WT_1  -36.674123 -41.688626
## WT_2   49.474829 -29.495301
## WT_3   -5.812515   4.905374
## cKO_1 -19.223942  -7.888048
## cKO_2  35.817169  13.070479
## cKO_3 -19.262162  26.568017
## cKO_4  -4.319256  34.528105
    # add phenodata column
    PCA.df <- transform(PCA.df, Pheno = c("WT", "WT", "WT", "cKO", "cKO", "cKO", "cKO"))
    PCA.df
##              PC1        PC2 Pheno
## WT_1  -36.674123 -41.688626    WT
## WT_2   49.474829 -29.495301    WT
## WT_3   -5.812515   4.905374    WT
## cKO_1 -19.223942  -7.888048   cKO
## cKO_2  35.817169  13.070479   cKO
## cKO_3 -19.262162  26.568017   cKO
## cKO_4  -4.319256  34.528105   cKO
    # plot using ggplot2 (better than base plot)
    ggplot(as.data.frame(PCA.df), aes(PC1, PC2)) +
      xlab(paste0("PC1, VarExp: ", percentVar[1], "%")) +
      ylab(paste0("PC2, VarExp: ", percentVar[2], "%")) + 
      geom_point() + theme_bw() +
      geom_text_repel(label = colnames(cDC1_gene_expression))+ 
      coord_fixed(ratio = 1)

pca

    # by colour
    ggplot(as.data.frame(PCA.df), aes(PC1, PC2, colour = Pheno)) +
      xlab(paste0("PC1, VarExp: ", percentVar[1], "%")) +
      ylab(paste0("PC2, VarExp: ", percentVar[2], "%")) + 
      geom_point() + theme_bw() +
      geom_text_repel(label = colnames(cDC1_gene_expression)) + 
      coord_fixed(ratio = 1)

pca_colour

    #############
    # probe annotation
    # we need to know gene name instead of probeID
    # just one example here
    mogene10sttranscriptcluster.db
## ChipDb object:
## | DBSCHEMAVERSION: 2.1
## | Db type: ChipDb
## | Supporting package: AnnotationDbi
## | DBSCHEMA: MOUSECHIP_DB
## | ORGANISM: Mus musculus
## | SPECIES: Mouse
## | MANUFACTURER: Affymetrix
## | CHIPNAME: mogene10
## | MANUFACTURERURL: http://www.affymetrix.com
## | EGSOURCEDATE: 2017-Mar29
## | EGSOURCENAME: Entrez Gene
## | EGSOURCEURL: ftp://ftp.ncbi.nlm.nih.gov/gene/DATA
## | CENTRALID: ENTREZID
## | TAXID: 10090
## | GOSOURCENAME: Gene Ontology
## | GOSOURCEURL: ftp://ftp.geneontology.org/pub/go/godatabase/archive/latest-lite/
## | GOSOURCEDATE: 2017-Mar29
## | GOEGSOURCEDATE: 2017-Mar29
## | GOEGSOURCENAME: Entrez Gene
## | GOEGSOURCEURL: ftp://ftp.ncbi.nlm.nih.gov/gene/DATA
## | KEGGSOURCENAME: KEGG GENOME
## | KEGGSOURCEURL: ftp://ftp.genome.jp/pub/kegg/genomes
## | KEGGSOURCEDATE: 2011-Mar15
## | GPSOURCENAME: UCSC Genome Bioinformatics (Mus musculus)
## | GPSOURCEURL: 
## | GPSOURCEDATE: 2017-Aug8
## | ENSOURCEDATE: 2017-Mar29
## | ENSOURCENAME: Ensembl
## | ENSOURCEURL: ftp://ftp.ensembl.org/pub/current_fasta
## | UPSOURCENAME: Uniprot
## | UPSOURCEURL: http://www.UniProt.org/
## | UPSOURCEDATE: Tue Sep 26 18:46:27 2017

## 
## Please see: help('select') for usage information
    pd.mogene.1.0.st.v1
## Class........: AffyGenePDInfo 
## Manufacturer.: Affymetrix 
## Genome Build.: MM10 
## Chip Geometry: 1050 rows x  1050 columns
    AnnotationDbi::columns(mogene10sttranscriptcluster.db)
##  [1] "ACCNUM"       "ALIAS"        "ENSEMBL"      "ENSEMBLPROT" 
##  [5] "ENSEMBLTRANS" "ENTREZID"     "ENZYME"       "EVIDENCE"    
##  [9] "EVIDENCEALL"  "GENENAME"     "GO"           "GOALL"       
## [13] "IPI"          "MGI"          "ONTOLOGY"     "ONTOLOGYALL" 
## [17] "PATH"         "PFAM"         "PMID"         "PROBEID"     
## [21] "PROSITE"      "REFSEQ"       "SYMBOL"       "UNIGENE"     
## [25] "UNIPROT"
    key <- AnnotationDbi::keys(mogene10sttranscriptcluster.db, keytype = "PROBEID")
    annot <- AnnotationDbi::select(mogene10sttranscriptcluster.db, 
                                   keys = key, 
                                   columns = c("SYMBOL", "GENENAME"), 
                                   keytype = "PROBEID")
## 'select()' returned 1:many mapping between keys and columns
    # you can see many probes not assigned to any genes
    # we remove these probes from further analysis here
    annot_NA <- dplyr::filter(annot, is.na(SYMBOL))
    annot <- dplyr::filter(annot, !is.na(SYMBOL))
    # you may also see some probes assigned to multiple genes
    # remove multiple assigned probes too
    anno_grouped <- group_by(annot, PROBEID)
    anno_summarized <- 
      dplyr::summarize(anno_grouped, no_of_matches = n_distinct(SYMBOL))
    tail(anno_summarized)
## # A tibble: 6 x 2
##   PROBEID  no_of_matches
##   <chr>            <int>
## 1 10608608            37
## 2 10608613            21
## 3 10608615            23
## 4 10608625            12
## 5 10608628            21
## 6 10608630            35
    anno_multimap <- filter(anno_summarized, no_of_matches > 1)
    head(anno_multimap)
## # A tibble: 6 x 2
##   PROBEID  no_of_matches
##   <chr>            <int>
## 1 10344713             2
## 2 10344719             2
## 3 10344741             3
## 4 10345030             2
## 5 10345079             3
## 6 10345083             3
    # convert matrix to tibble
    # rowname (PROBEID) to 1st column
    cDC1_gene_expression_tb <- as.data.frame(cDC1_gene_expression) %>%
      tibble::rownames_to_column(var = "PROBEID")

    # remove unmapped or multi-mapped probes from expression data
    # %in% is an operater meaning if an element belongs to a vector
    cDC1_gene_expression_filtered <- cDC1_gene_expression_tb %>% 
      dplyr::filter(!(PROBEID %in% c(anno_multimap$PROBEID, annot_NA$PROBEID)))

    cDC1_gene_expression_filtered <- cDC1_gene_expression_tb %>% 
      dplyr::filter(!(PROBEID %in% c(anno_multimap$PROBEID, annot_NA$PROBEID)))

    # we conduct DEA without unmapped or multi-mapped probes
    str(cDC1_gene_expression)
##  num [1:35556, 1:7] 12.51 5.19 10.86 9.36 2.54 ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : chr [1:35556] "10338001" "10338002" "10338003" "10338004" ...
##   ..$ : chr [1:7] "WT_1" "WT_2" "WT_3" "cKO_1" ...
    str(cDC1_gene_expression_filtered)
## 'data.frame':    22098 obs. of  8 variables:
##  $ PROBEID: chr  "10344624" "10344633" "10344637" "10344653" ...
##  $ WT_1   : num  7.72 8.15 7.25 3.34 6.77 ...
##  $ WT_2   : num  7.03 8.65 7.86 3.45 6.98 ...
##  $ WT_3   : num  7.72 8.63 7.38 3.34 6.85 ...
##  $ cKO_1  : num  7.52 8.24 7.34 3.34 7.27 ...
##  $ cKO_2  : num  7.83 8.4 7.64 3.4 6.87 ...
##  $ cKO_3  : num  8.01 8.86 7.34 3.31 6.98 ...
##  $ cKO_4  : num  7.8 8.7 7.28 3.14 7.02 ...
    # convert data type for limma
    cDC1_gene_expression <- cDC1_gene_expression_filtered %>% 
      tibble::column_to_rownames(var = "PROBEID")
    str(cDC1_gene_expression)
## 'data.frame':    22098 obs. of  7 variables:
##  $ WT_1 : num  7.72 8.15 7.25 3.34 6.77 ...
##  $ WT_2 : num  7.03 8.65 7.86 3.45 6.98 ...
##  $ WT_3 : num  7.72 8.63 7.38 3.34 6.85 ...
##  $ cKO_1: num  7.52 8.24 7.34 3.34 7.27 ...
##  $ cKO_2: num  7.83 8.4 7.64 3.4 6.87 ...
##  $ cKO_3: num  8.01 8.86 7.34 3.31 6.98 ...
##  $ cKO_4: num  7.8 8.7 7.28 3.14 7.02 ...
    #################
    # differential gene expression analysis by limma package
    # make contrast.matrix 
    groups <- factor(c(0, 0, 0, 1, 1, 1, 1))
    groups
## [1] 0 0 0 1 1 1 1
## Levels: 0 1
    design <- model.matrix(~ 0 + groups)
    design
##   groups0 groups1
## 1       1       0
## 2       1       0
## 3       1       0
## 4       0       1
## 5       0       1
## 6       0       1
## 7       0       1
## attr(,"assign")
## [1] 1 1
## attr(,"contrasts")
## attr(,"contrasts")$groups
## [1] "contr.treatment"
    colnames(design) <- c("WT", "cKO")
    design
##   WT cKO
## 1  1   0
## 2  1   0
## 3  1   0
## 4  0   1
## 5  0   1
## 6  0   1
## 7  0   1
## attr(,"assign")
## [1] 1 1
## attr(,"contrasts")
## attr(,"contrasts")$groups
## [1] "contr.treatment"
    contrast.matrix <- makeContrasts(WTvscKO = WT - cKO, levels = design)
    contrast.matrix
##       Contrasts
## Levels WTvscKO
##    WT        1
##    cKO      -1
    # fit to linear model
    fit <- lmFit(cDC1_gene_expression, design)
    fit2 <- contrasts.fit(fit, contrast.matrix)
    fit2 <- eBayes(fit2, proportion = 0.01)
    topTable(fit2)
##              logFC   AveExpr         t      P.Value    adj.P.Val        B
## 10534493 -6.550408  8.840045 -87.20756 3.624331e-11 8.009047e-07 8.136083
## 10364038 -3.300669  7.288904 -42.67066 3.642851e-09 4.024986e-05 7.658134
## 10576807 -4.827990  7.448193 -33.10386 1.865703e-08 1.374276e-04 7.288831
## 10498367 -2.802876  6.233213 -30.18603 3.374964e-08 1.551310e-04 7.114609
## 10493995 -4.152279 11.000441 -30.00204 3.510070e-08 1.551310e-04 7.102219
## 10548314 -3.328394  8.468356 -26.82584 7.195771e-08 2.650203e-04 6.855729
## 10539135 -4.969217  8.079582 -23.59303 1.637443e-07 5.169173e-04 6.524127
## 10576784 -2.623773  7.948250 -22.97149 1.942206e-07 5.364859e-04 6.448320
## 10362803 -2.181507  8.483018 -22.33110 2.326781e-07 5.713024e-04 6.365395
## 10573939 -2.403545  8.702084 -17.91644 9.463242e-07 1.880787e-03 5.624748
    top250 <- topTable(fit2, adjust="fdr", sort.by="B", number=250) 

    # summmary and visualisation
    summary(decideTests(fit2))
##        WTvscKO
## Down        63
## NotSig   22032
## Up           3
    limma::plotMA(fit2)

limma_ma

    limma::plotSA(fit2)

limma_sp

    limma::volcanoplot(fit2)

limma_vp

    # save limma's result
    # convert again
    # There must be better way
    # PROBEID 1st column
    # tibbleのrownames_to_columnという便利な関数がある
    limma_result <- topTable(fit2, sort.by = "logFC", 
                             adjust.method = "fdr", number = Inf) %>% 
      tibble::rownames_to_column(var = "PROBEID")

    # time to join
    # use left_join to combine limma result and probe annotation data.
    limma_result_gene <- dplyr::left_join(limma_result, annot, by = "PROBEID")
    write.table(limma_result_gene, file = "limma_result_gene.txt", sep = "\t", row.names = F)
    # multiple test
    # adjusted P value < 0.05
    # as differential expressed genes
    limma_DEG <- limma_result_gene %>% 
      dplyr::filter(adj.P.Val < 0.05)
    # finish
    ########
    # visualisation
    # add gene symbol
    cDC1_gene_expression_filtered_gene <- cDC1_gene_expression_filtered %>% 
      dplyr::left_join(annot, by = "PROBEID")

    Zeb2 <- filter(cDC1_gene_expression_filtered_gene, SYMBOL == "Zeb2") %>% select(2:8) 
    barplot(as.matrix(Zeb2), xlab = "sample", ylab = "log2 expression", main = "Zeb2", las = 3)

zeb2

    Ccl24 <- filter(cDC1_gene_expression_filtered_gene, SYMBOL == "Ccl24") %>% select(2:8) 
    barplot(as.matrix(Ccl24), xlab = "sample", ylab = "log2 expression", main = "Ccl24", las = 3)

Ccl24

    # limma_result_merge <- merge(limma_result, anno_summarized, by = "PROBEID", all.x = F)

    # let's use ggplot2
    # MA plot
    ma <- ggplot(data = limma_result, aes(x = AveExpr, y = logFC)) + 
      geom_point(size = 0.4) +
      geom_point(data = limma_DEG, colour = "red", size = 0.7) + 
      theme_classic()
    ma

ma

    # rabel gene symbol by ggrepel
    ma + geom_text_repel(data = limma_DEG, aes(label = SYMBOL))

ma_ggrepel

    # volcano plot
    vp <- ggplot(data = limma_result, aes(x = logFC, y = -log10(P.Value))) +
      geom_point(size = 0.3) +
      geom_point(data = limma_DEG, colour = "red", size = 0.3) +
      theme_classic()
    vp

volcano

    vp + geom_text_repel(data = limma_DEG, aes(label = SYMBOL))

volcano_ggrepel

    # heatmap
    # gplots::heatmap.2()
    heatmap_DEG <- cDC1_gene_expression_filtered_gene %>% 
      filter(SYMBOL %in% limma_DEG$SYMBOL) %>% 
      select(SYMBOL, everything()) %>% select(1,3:9) %>% 
      distinct(SYMBOL, .keep_all = TRUE) %>% 
      tibble::column_to_rownames(var = "SYMBOL")

    heatmap.2(as.matrix(heatmap_DEG), col = brewer.pal(11,"RdBu"), trace = "none", cexCol = 0.9, cexRow = 0.5, scale = "row")

heatmap_RdBu

    heatmap.2(as.matrix(heatmap_DEG), col = brewer.pal(9,"YlGnBu"), trace = "none", cexCol = 0.9, cexRow = 0.5, scale = "row")

heatmap_YlGuBu

    heatmap.2(as.matrix(heatmap_DEG), col = bluered(256), trace = "none", cexCol = 0.9, cexRow = 0.5, scale = "row")

heatmap_bluered256

    Seurat <- colorRampPalette(c("#FF00FF", "#000000", "#FFFF00"))
    heatmap.2(as.matrix(heatmap_DEG), col = Seurat, trace = "none", cexCol = 0.9, cexRow = 0.5, scale = "row")

heatmap_seurat

    sessionInfo()
## R version 3.6.0 (2019-04-26)
## Platform: x86_64-apple-darwin15.6.0 (64-bit)
## Running under: macOS Mojave 10.14.4
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] ja_JP.UTF-8/ja_JP.UTF-8/ja_JP.UTF-8/C/ja_JP.UTF-8/ja_JP.UTF-8
## 
## attached base packages:
## [1] stats4    parallel  stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] RColorBrewer_1.1-2                  
##  [2] viridis_0.5.1                       
##  [3] viridisLite_0.3.0                   
##  [4] ggrepel_0.8.1                       
##  [5] gplots_3.0.1.1                      
##  [6] forcats_0.4.0                       
##  [7] stringr_1.4.0                       
##  [8] dplyr_0.8.3                         
##  [9] purrr_0.3.3                         
## [10] readr_1.3.1                         
## [11] tidyr_1.0.0                         
## [12] tibble_2.1.3                        
## [13] ggplot2_3.2.1                       
## [14] tidyverse_1.2.1                     
## [15] limma_3.40.6                        
## [16] pd.mogene.1.0.st.v1_3.14.1          
## [17] DBI_1.0.0                           
## [18] oligo_1.48.0                        
## [19] oligoClasses_1.46.0                 
## [20] RSQLite_2.1.2                       
## [21] Biostrings_2.52.0                   
## [22] XVector_0.24.0                      
## [23] mogene10sttranscriptcluster.db_8.7.0
## [24] org.Mm.eg.db_3.8.2                  
## [25] AnnotationDbi_1.46.1                
## [26] IRanges_2.18.3                      
## [27] S4Vectors_0.22.1                    
## [28] GEOquery_2.52.0                     
## [29] Biobase_2.44.0                      
## [30] BiocGenerics_0.30.0                 
## [31] BiocManager_1.30.9                  
## 
## loaded via a namespace (and not attached):
##  [1] nlme_3.1-141                bitops_1.0-6               
##  [3] matrixStats_0.55.0          lubridate_1.7.4            
##  [5] bit64_0.9-7                 httr_1.4.1                 
##  [7] GenomeInfoDb_1.20.0         tools_3.6.0                
##  [9] backports_1.1.5             utf8_1.1.4                 
## [11] R6_2.4.0                    affyio_1.54.0              
## [13] KernSmooth_2.23-16          lazyeval_0.2.2             
## [15] colorspace_1.4-1            withr_2.1.2                
## [17] gridExtra_2.3               tidyselect_0.2.5           
## [19] bit_1.1-14                  compiler_3.6.0             
## [21] preprocessCore_1.46.0       cli_1.1.0                  
## [23] rvest_0.3.4                 xml2_1.2.2                 
## [25] DelayedArray_0.10.0         labeling_0.3               
## [27] caTools_1.17.1.2            scales_1.0.0               
## [29] digest_0.6.22               rmarkdown_1.16             
## [31] pkgconfig_2.0.3             htmltools_0.4.0            
## [33] readxl_1.3.1                rlang_0.4.1                
## [35] rstudioapi_0.10             generics_0.0.2             
## [37] jsonlite_1.6                gtools_3.8.1               
## [39] BiocParallel_1.18.1         RCurl_1.95-4.12            
## [41] magrittr_1.5                GenomeInfoDbData_1.2.1     
## [43] Matrix_1.2-17               fansi_0.4.0                
## [45] Rcpp_1.0.2                  munsell_0.5.0              
## [47] lifecycle_0.1.0             stringi_1.4.3              
## [49] yaml_2.2.0                  SummarizedExperiment_1.14.1
## [51] zlibbioc_1.30.0             grid_3.6.0                 
## [53] affxparser_1.56.0           blob_1.2.0                 
## [55] gdata_2.18.0                crayon_1.3.4               
## [57] lattice_0.20-38             haven_2.1.1                
## [59] splines_3.6.0               hms_0.5.2                  
## [61] zeallot_0.1.0               knitr_1.25                 
## [63] pillar_1.4.2                GenomicRanges_1.36.1       
## [65] codetools_0.2-16            glue_1.3.1                 
## [67] evaluate_0.14               modelr_0.1.5               
## [69] vctrs_0.2.0                 foreach_1.4.7              
## [71] cellranger_1.1.0            gtable_0.3.0               
## [73] assertthat_0.2.1            xfun_0.10                  
## [75] broom_0.5.2                 ff_2.2-14                  
## [77] iterators_1.0.12            memoise_1.1.0