Changelog
Source:NEWS.md
GEOquery 2.81.32
New features
-
geoToSRA()resolves a GEO Series or Sample (GSE/GSM) to its underlying Sequence Read Archive accessions — returning a tidydata.frameofgeo_accession,srp,srx,srr,srs(study/experiment/run/sample) by cross-referencing NCBI Entrez (gds→sra). This is the accession-linking bridge to raw sequencing data; it downloads no sequence files. See ADR-0008 (#219). -
searchGEO()now uses a batched JSON esummary backend (esummary db=gds&retmode=json&version=2.0) instead of fetching and string-parsing one text record at a time. This is faster on large result sets and returns structured, stably-named columns:Accession,Title,Summary,Organism,Type,GPL,n_samples,PDAT,suppFile,FTPLink,SeriesTitle,entryType, andID. Adds a lightweightjsonlitedependency (#223).
Internal
- Downloaded and cached files can now be integrity-checked against an expected MD5.
downloadFile()gains an opt-inmd5=argument; a mismatch emits a structuredgeoquery_checksum_mismatchwarning (advisory, not an error) and the corrupt file is not cached. Foundational for the raw-file resolver and fetch receipt (#222).
GEOquery 2.81.31 (2026-07-18)
Deprecated
-
GDS2MA()is deprecated and now warns; it will be removed in a future release. Itslimma::MAListreturn type is superseded byGDS2eSet()’sExpressionSet(coercible toSummarizedExperimentand other downstream structures).limmamoves fromImportstoSuggestsaccordingly, so it is no longer installed with GEOquery;GDS2MA()errors with a clear message iflimmais absent (#217).
GEOquery 2.81.30 (2026-07-18)
Internal
- Dropped the
rvestandstringrdependencies (no user-facing change). GEO download-page link parsing now usesxml2(already a dependency) and the remaining string helpers use base R; the extracted.extractGeoDownloadLinks()is covered by a new offline test (#216).
GEOquery 2.81.29 (2026-07-18)
Bug fixes
- Printing a
GSM,GPL, orGDSobject now shows the leading rows of its data table again. A corrupted definition of the internalprintHead()helper had made it return a function instead of printing, so the “Data Table” preview in theshow()method was broken (#215).
GEOquery 2.81.28 (2026-07-17)
Documentation
- Restructured the vignettes into a coherent six-document set, all installed with the package: Getting started, Understanding GEO data formats, Finding and downloading data (new — covers
searchGEO(), download control, persistent caching/reproducibility, and reviewer-token access), RNA-seq quantifications, Single-cell data from GEO, and From GEO to downstream analysis. The in-depth articles are now built as vignettes (previously website-only) so they are available offline and on the Bioconductor landing page. Vignette code is precompiled from*.qmd.origsources (seedev/precompute-vignettes.R) so it shows real GEO output while package/CI builds make no network calls.
GEOquery 2.81.27 (2026-07-17)
New features
-
getGEOSingleCell()now attaches each sample’s GEO metadata — the parsedcharacteristics_*fields (age, sex, genotype, tissue, treatment, …),title, and source name — to the returned object’scolData, broadcast across that sample’s cells, controlled by a newaddSampleMetaargument (defaultTRUE). The columns are prefixedsample.to avoid clashing with the importer’s owncolData, and they survive combining across samples (by = "platform"/by = "all"), which now reconciles differingcolDatacolumns (union, NA-filled). The metadata comes from the Series Matrix pData (a GSE) or the GSM SOFT record (a lone GSM); whole-study files with no GSM get nothing. Previously the single-cell matrices carried no phenotype information at all (#210, split from #158).
GEOquery 2.81.26 (2026-07-17)
New features
-
getGEO()andgetGEOfile()gain atokenargument for fetching private/embargoed GEO records with an NCBI GEO reviewer access token (obtained from the “Reviewer access” link on the private GSE’s page). Because private records are not published to the GEO FTP tree, a token forces the SOFT (acc.cgi) download path and appends the token to the request; for a GSE this returns aGSES4 object (as withGSEMatrix = FALSE) rather than aSummarizedExperiment. See ADR-0007 (#154).
GEOquery 2.81.25 (2026-07-17)
Bug fixes
- Series Matrix records whose
ID_REFrepeats a feature identifier (common when the IDs are gene symbols, e.g. GSE136400 withCXXC1twice) no longer fail withduplicate row.names: ... AnnotatedDataFrame 'initialize' could not update varMetadata. Duplicate feature IDs are now made unique withmake.unique(), mirroring the existing guard inGDS2eSet()(#98). -
getGEO(filename=)on a metadata-only SOFT file — such as the truncated output ofgetGEOfile(amount = "quick")or"brief", which contains no^SAMPLE/^PLATFORMentities — now returns aGSEobject with empty sample/platform lists instead of erroring withinvalid 'n' argument/NA/NaN argument(#14). -
getGSEDataTables()now always returns a list of data.frames, including when a Series carries exactly one<Data-Table>(previously a single-table Series such as GSE98638 was mis-simplified into a character matrix). This makes series-level annotation tables — e.g. a single-cell study’s per-cell “Listing of Individual Cells” table — reliably accessible (#80).
New features
-
getGEO()gains anencodingargument ("unknown"(default),"UTF-8", or"Latin-1") for the occasional non-UTF-8 GEO record. It sets the character encoding used by the underlyingdata.table::fread()reads for the duration of the call; the same override is available globally viaoptions(GEOquery.encoding = ...)(#148).
GEOquery 2.81.24 (2026-07-17)
Bug fixes
-
extractFilenameFromDownloadURL()— and thereforegetRNASeqQuantGenomeInfo()— no longer errors when handed an empty (zero-length) URL, as happens when a Series has no NCBI-computed RNA-seq annotation link. It now returnsNULLas documented instead of raising anhttr2::url_parse()error (#207).
Testing / infrastructure
- Added deterministic, network-free unit tests for the pure helper functions in the RNA-seq (
R/rnaseq.R), Entrez-search (R/searchGEO.R), SOFT-parsing (R/parseGEO.R), supplemental-file, GDS-conversion, and file-open code paths, raising baseline coverage (#207). - New
skip_if_geo_offline()test helper (mirroring BiocPkgTools’skip_if_bioc_offline()) probes NCBI GEO reachability so network-dependent tests run when the host is up and skip cleanly when it is not (#207, #169).
GEOquery 2.81.23 (2026-06-16)
New features
- Seurat interoperability for single-cell data (optional;
SeuratinSuggests).readGEOSingleCell()now reads.rdssupplementary files containing a Seurat orSingleCellExperimentobject (detected by class; Seurat coerced toSingleCellExperiment), so.rdsis now a loadable single-cell format. BothreadGEOSingleCell()andgetGEOSingleCell()gainas = "Seurat"to return Seurat objects (coerced at the output boundary).SingleCellExperimentremains the internal representation; see ADR-0006 (#195, #196, #197).
GEOquery 2.81.22 (2026-06-14)
New features
-
geoSingleCellManifest()andgetGEOSingleCell()now handle the common case where a Series ships only aGSE..._RAW.tarat the series level and the per-sample files live in each sample’s own GSM suppl directory (e.g. GSE132771). When the series level has no loadable single-cell units, the manifest falls back to enumerating the Series’ samples (viagetGEO()) and inventorying each GSM suppl directory. Both functions also accept a GSM accession directly (getGEOSingleCell("GSM3891612")), andgeoSingleCellManifest()gains asamplesargument to restrict to specific GSMs without enumerating the whole Series. Unit files are downloaded by URL, so the readers work whether the data lives at the series or sample level (#190). -
getGEOSingleCell()gains abyargument — one of"sample"(default; a named list of oneSingleCellExperimentper sample),"platform"(a named list keyed by platform/GPL, each platform’s samples combined), or"all"(a single combined object) — replacing the previouscombineflag. A GEO Series can span multiple platforms (e.g. GSE132771 mixes mouse and human), and the platform is the natural feature-compatibility boundary, soby = "platform"is the right way to combine a multi-platform study; the return shape is determined by the argument, not the data.geoSingleCellManifest()now reports aplatform(GPL) column per sample, andgeoSingleCellUnits()treats each whole-study single file as its own unit so a study’s several.h5adfiles are no longer merged into one bogus unit. Gzipped single-file formats (.h5ad.gz,.h5.gz) are recognized and transparently decompressed before reading. loom is reported but flagged not loadable, no built-in reader (.rds/Seurat support follows in 2.81.23) (#190).
Bug Fixes
- Combining single-cell samples (
getGEOSingleCell(by = "platform"|"all")) no longer fails with a crypticcbinderror ('mcols' ... do not matchorsubscript contains invalid names) when a Series’ samples have heterogeneous feature annotation — common in single-cell studies (e.g. GSE132771 mixes 10x CellRanger v2genes.tsvwith v3features.tsv, giving different rowData columns). Samples are restricted to their shared features and given one canonical rowData before binding; when they share no features (so a single combined object is impossible) a clear, actionable error is raised (#190).
GEOquery 2.81.21 (2026-06-13)
Breaking changes
-
getGEO()now returnsSummarizedExperimentobjects by default for GSE Series Matrix records (previouslyExpressionSet). Update downstream code fromexprs()/pData()/fData()toassay()/colData()/rowData(), or passreturnType = "ExpressionSet"to keep the old behavior. Existing results can also be converted withas_SummarizedExperiment(). SOFT-format results (GDS/GPL/GSM/GSE S4 objects) are unaffected. See ADR-0002 and ADR-0005 (#168).
New features
- Optional persistent download cache backed by BiocFileCache. Set
options(GEOquery.cache = TRUE)to have downloads keyed on their URL and reused across sessions (location defaults totools::R_user_dir("GEOquery", "cache"), overridable viaoptions(GEOquery.cache.path = ...)). NewgeoCache()andclearGEOCache()expose and clear it. Off by default for now, preserving the historicaldestdirbehavior (#171). - New
readGEOSingleCell()andgetGEOSingleCell()read GEO single-cell supplementary data intoSingleCellExperimentobjects: 10x Matrix Market and 10x HDF5 via TENxIO, AnnData.h5advia anndataR (optionalSuggests).getGEOSingleCell()returns a named list of per-sample objects (combine with care) and reports which units it loads and skips. loom, files inside_RAW.tar, and idiosyncratic layouts are intentionally out of scope — usegeoSingleCellManifest()+readGEOSingleCell()for those (#158, #190). - New
geoSingleCellManifest()inventories a GSE’s supplementary files and classifies them by single-cell format (10x Matrix Market triplet, 10x HDF5, AnnData h5ad, loom, Seurat rds, tar), grouping by GSM sample — so you can see what a single-cell study contains before downloading.geoSingleCellUnits()collapses the manifest into loadable units (per sample + format) and flags completeness (e.g. an incomplete 10x triplet). Steps toward single-cell readers (ADR-0004) (#158, #188, #189). -
getGEO()gains areturnTypeargument. WithreturnType = "SummarizedExperiment", GSE Series Matrix results are returned asSummarizedExperimentobjects instead ofExpressionSet. The default remains"ExpressionSet"for now (with a one-time notice) and will switch to"SummarizedExperiment"in a future release. A new exportedas_SummarizedExperiment()coerces an existingExpressionSetresult without re-downloading. See ADR-0002 (#168). - Downloads now stream to disk instead of buffering the entire response in memory, retry on transient HTTP errors, and honor a configurable
GEOquery.download.timeoutoption (default 300 seconds) — replacing the previous enforced 120-second floor that ignored lower user timeouts. Failures raise a typedgeoquery_download_errorcarrying the URL and HTTP status.getDirListing()now uses the same httr2 layer (#147, #173). - GEOquery now raises typed error conditions —
geoquery_errorand subclasses (geoquery_private_accession,geoquery_download_error,geoquery_parse_error,geoquery_bad_accession) — so failures can be handled programmatically withtryCatch()(#170, #184, #186). -
getGEOSuppFiles()gains aquietargument (defaulting to theGEOquery.quietoption, orFALSE) to suppress informational messages such as “No supplemental files found” and “Using locally cached version” (#68, #182).
Documentation
The S4 class and accessor documentation is filled in: the
GEODataaccessors (Meta,Table,Columns,dataTable,Accession,GSMList,GPLList) now have real descriptions, return values, and examples, and the class pages no longer imply constructing objects withnew()— they are returned bygetGEO()(#103, #192).Documentation is reorganized into narrative pkgdown articles — Understanding GEO data formats, RNA-seq quantifications, Single-cell data from GEO, and From GEO to downstream analysis — that cover the why (entity types, file formats) and downstream workflows with links to other Bioconductor packages. The package vignette is now a concise quick-start that indexes them; the articles render on the pkgdown site and are excluded from
R CMD check(#156, #191).The package
DESCRIPTIONandbiocViewsnow describe GEOquery’s actual scope (microarray, RNA-seq, and single-cell; GEO Series Matrix files parsed toExpressionSetby default) instead of microarray-only (#71, #181).
Bug Fixes
- Supplemental-file URLs are now built with a small
url_join()helper instead offile.path(), which mangledhttps://intohttps:/and produced double slashes. AffectsgetGEOSuppFiles(fetch_files = FALSE)andgetGEOSeriesFileListing()(#131, #178). -
GDS2eSet()no longer fails when a GDS has anNA(or empty) value in itsID_REFcolumn (e.g. GDS3666). Such values are replaced with a usable feature name instead of producing “row names contain missing values” (#21, #177). -
getGEO()now fails with a clear message when an accession is private, embargoed, or not yet public (NCBI returns an HTML page) instead of mis-parsing it or, in older versions, looping.findFirstEntity()is also hardened against a multi-line edge case that could error and against unbounded reads (#58, #176). -
getGEO(parseCharacteristics = FALSE)now actually skips characteristics parsing. The flag was accepted at the top level but dropped before reachingparseGSEMatrix(); it is now threaded throughgetAndParseGSEMatrices()andparseGEO()(#60, #175). - Fixed error when parsing GSE matrix files with malformed or empty lines between sample metadata (e.g., GSE425). Sample lines are now extracted directly using pattern matching to avoid issues with irregular file formatting (#162).