Most GEOquery examples assume you already have an accession. This article covers the steps before and around that: finding studies programmatically, controlling what getGEO() fetches, caching downloads for reproducible work, and reaching private records under review.
library(GEOquery)If you do not yet have an accession, searchGEO() queries the NCBI GEO DataSets database with the standard Entrez syntax and returns one row per hit:
res <- searchGEO("asthma[Title] AND GSE[ETYP]")
nrow(res)
#> [1] 387
res[1:5, c("Series Accession", "Title", "Organism")]
#> Series Accession
#> 1 GSE301357
#> 2 GSE325572
#> 3 GSE334345
#> 4 GSE332995
#> 5 GSE297032
#> Title
#> 1 The airway transcriptome in type2 cytokine biomarker-high and -low severe asthma
#> 2 Transcriptomic analyses identify TMPRSS4 as a shared biomarker in asthma and atopic dermatitis
#> 3 Exploratory investigation of changes in blood transcriptome following mepolizumab treatment for asthma
#> 4 Shuangpi Formula Treats Neutrophilic Asthma via Circadian-Mediated Anti-Inflammatory Mechanisms
#> 5 Atopic asthma lowers nasal mucosal sphingolipids
#> Organism
#> 1 Homo sapiens
#> 2 Homo sapiens
#> 3 Homo sapiens
#> 4 Rattus norvegicus
#> 5 Homo sapiensThe query uses Entrez field tags — [Title], [Organism], [Description], [ETYP] (entity type, e.g. GSE), and many more — combined with AND / OR. To see the fields available for searching:
head(searchFieldsGEO(), 12)
#> Name FullName Description TermCount IsDate IsNumerical SingleToken
#> 1 ALL All Fields All term.... 48154253 N N N
#> 2 UID UID Unique n.... 0 N Y Y
#> 3 FILT Filter Limits t.... 71 N N Y
#> 4 ORGN Organism exploded.... 78347 N N Y
#> 5 ACCN GEO Acce.... accessio.... 20700173 N N Y
#> 6 TITL Title Words in.... 10584350 N N Y
#> 7 DESC Description Text fro.... 11474236 N N Y
#> 8 SFIL Suppleme.... Suppleme.... 256 N N Y
#> 9 ETYP Entry Type Entry ty.... 4 N N Y
#> 10 STYP Sample Type Sample type 9 N N Y
#> 11 VTYP Sample V.... type of .... 7 N N Y
#> 12 PTYP Platform.... Platform.... 17 N N Y
#> Hierarchy IsHidden
#> 1 N N
#> 2 N Y
#> 3 N N
#> 4 Y N
#> 5 N N
#> 6 N N
#> 7 N N
#> 8 N N
#> 9 N N
#> 10 N N
#> 11 N N
#> 12 N NOnce a hit looks promising, hand its accession straight to getGEO():
gse <- getGEO(res[["Series Accession"]][1])To open a record in your web browser instead — handy for eyeballing a study before committing to a download — use browseGEOAccession():
browseGEOAccession("GSE2553")getGEO() fetchesgetGEO() has a few knobs worth knowing:
# Default: fast Series Matrix path -> list of SummarizedExperiment
getGEO("GSE2553")
# Legacy container instead of SummarizedExperiment
getGEO("GSE2553", returnType = "ExpressionSet")
# Skip the platform (GPL) download when you don't need feature annotation;
# faster, and avoids fetching a large platform table
getGEO("GSE2553", getGPL = FALSE)
# Full SOFT record (a GSE S4 object) instead of the Series Matrix
getGEO("GSE2553", GSEMatrix = FALSE)
# Store the downloaded file somewhere stable (see Caching, below)
getGEO("GSE2553", destdir = "~/geo-cache")
# Override character encoding for the rare non-UTF-8 record
getGEO("GSE2553", encoding = "Latin-1")The encoding override is also available globally with options(GEOquery.encoding = "Latin-1") for a whole session.
Processed expression tables are only part of a study; raw and processed supplementary files (RNA-seq counts, single-cell matrices, and more) are listed and downloaded separately. Always look before you leap:
getGEOSuppFiles("GSE63137", fetch_files = FALSE) # inspect: a data.frame of files
#> fname
#> 1 GSE63137_ATAC-seq_PV_neurons_HOMER_peaks.bed.gz
#> 2 GSE63137_ATAC-seq_VIP_neurons_HOMER_peaks.bed.gz
#> 3 GSE63137_ATAC-seq_excitatory_neurons_HOMER_peaks.bed.gz
#> 4 GSE63137_ChIP-seq_H3K27ac_excitatory_neurons_SICER_peaks.bed.gz
#> 5 GSE63137_ChIP-seq_H3K27me3_excitatory_neurons_SICER_peaks.bed.gz
#> 6 GSE63137_ChIP-seq_H3K4me1_excitatory_neurons_SICER_peaks.bed.gz
#> 7 GSE63137_ChIP-seq_H3K4me3_excitatory_neurons_SICER_peaks.bed.gz
#> 8 GSE63137_MethylC-seq_DMRs_methylpy.txt.gz
#> 9 GSE63137_MethylC-seq_PV_neurons_UMRs_LMRs.txt.gz
#> 10 GSE63137_MethylC-seq_VIP_neurons_UMRs_LMRs.txt.gz
#> 11 GSE63137_MethylC-seq_excitatory_neurons_UMRs_LMRs.txt.gz
#> 12 GSE63137_RAW.tar
#> url
#> 1 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_ATAC-seq_PV_neurons_HOMER_peaks.bed.gz
#> 2 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_ATAC-seq_VIP_neurons_HOMER_peaks.bed.gz
#> 3 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_ATAC-seq_excitatory_neurons_HOMER_peaks.bed.gz
#> 4 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_ChIP-seq_H3K27ac_excitatory_neurons_SICER_peaks.bed.gz
#> 5 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_ChIP-seq_H3K27me3_excitatory_neurons_SICER_peaks.bed.gz
#> 6 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_ChIP-seq_H3K4me1_excitatory_neurons_SICER_peaks.bed.gz
#> 7 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_ChIP-seq_H3K4me3_excitatory_neurons_SICER_peaks.bed.gz
#> 8 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_MethylC-seq_DMRs_methylpy.txt.gz
#> 9 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_MethylC-seq_PV_neurons_UMRs_LMRs.txt.gz
#> 10 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_MethylC-seq_VIP_neurons_UMRs_LMRs.txt.gz
#> 11 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_MethylC-seq_excitatory_neurons_UMRs_LMRs.txt.gz
#> 12 https://ftp.ncbi.nlm.nih.gov/geo/series/GSE63nnn/GSE63137/suppl/GSE63137_RAW.targetGEOSuppFiles("GSE63137") # download all into ./GSE63137/By default, GEOquery downloads to a temporary directory (destdir = tempdir()), which R clears at the end of the session — so the same getGEO() call re-downloads every session. For interactive work and reproducible pipelines you usually want downloads to persist. Two options:
Point destdir at a stable directory on any call that downloads:
getGEO("GSE2553", destdir = "~/geo-cache")
getGEOSuppFiles("GSE63137", baseDir = "~/geo-cache")Or turn on the built-in persistent cache, backed by BiocFileCache. Once enabled, repeated downloads of the same URL are served from disk across sessions:
options(GEOquery.cache = TRUE) # enable for the session
options(GEOquery.cache.path = "~/geo-cache") # optional: choose the location
geoCache() # the BiocFileCache object backing the cache
clearGEOCache() # wipe it when you want a clean re-downloadFor results you intend to publish, record what you used: pin a stable destdir or the cache, and capture sessionInfo() (GEOquery and dependency versions) alongside your output. GEO records can change over time, so a saved object plus a version record is the difference between reproducible and “worked on my machine.”
Records still under peer review are not published to GEO’s public FTP tree, so a normal getGEO() cannot see them. If you have a reviewer access token (the “Reviewer access” link on the private GSE’s page), pass it with token:
gse <- getGEO("GSE123456", token = "yourreviewertoken")Because private records bypass the FTP tree, a token forces the SOFT (acc.cgi) download path. For a GSE that means you get a GSE S4 object (as with GSEMatrix = FALSE) rather than a SummarizedExperiment.