Skip to content

fix: detect the header of Visium tissue positions files from their contents - #10534

Open
MMatinGerami wants to merge 1 commit into
satijalab:mainfrom
MMatinGerami:fix/read10x-coordinates-header
Open

MMatinGerami wants to merge 1 commit into
satijalab:mainfrom
MMatinGerami:fix/read10x-coordinates-header

Conversation

@MMatinGerami

@MMatinGerami MMatinGerami commented Oct 24, 2026 •

Copy link
Copy Markdown

Summary

Read10X_Coordinates() decided whether a tissue positions CSV has a header from the file name alone (header = basename(filename) == "tissue_positions.csv"). Files are often renamed, for example on GEO, so:

This PR detects the header from the first line instead: in a data row the second field (in_tissue) is always 0 or 1, so the line is treated as a header otherwise (quotes are stripped first).

Type of change

  • Bug fix (non-breaking change fixing an issue)
  • New feature (non-breaking change adding functionality)
  • Breaking change (existing functionality changed or removed)
  • Documentation update
  • Other (please explain below)

Motivation

Users loading Visium data downloaded from GEO keep hitting #9240 (reports up to Dec 2025), and the header assumption was identified in the issue thread.

Tests & examples

A new test in tests/testthat/test_load_10X.R writes the bundled tissue_positions_list.csv with a header under a GEO-style _list name, and without a header under the tissue_positions.csv name, and checks that both read as numeric coordinates with the right number of spots and give the same result as the original file. Before the fix 7 expectations fail (character columns; 4993 and 4991 rows instead of 4992); with the fix test_load_10X.R passes (10 tests, 66 expectations), as does test_spatial.R.

# run from tests/testthat; same test data as test_load_10X.R
src <- file.path("../testdata/visium", "spatial", "tissue_positions_list.csv")
f <- file.path(tempdir(), "GSM1_tissue_positions_list.csv")
writeLines(c("barcode,in_tissue,array_row,array_col,pxl_row_in_fullres,pxl_col_in_fullres", readLines(src)), f)
str(Read10X_Coordinates(f, filter.matrix = TRUE))
# before: imagerow chr ...; Read10X_Image() then errors
# after:  imagerow int ...

Related issues

Closes #9240

Checklist

  • Branch is named appropriately (feat/*, fix/*, docs/*)
  • Code follows Seurat style guidelines
  • Documentation and comments have been updated (NEWS.md entry under Unreleased / Fixes)
  • devtools::document() has been run (not needed: no roxygen or exported signature changed)
  • devtools::check() passes with no errors or warnings (not run locally; I ran the affected test files)
  • Test case demonstrating new functionality is included
  • Maintainers are allowed to edit this PR

…ntents

Read10X_Coordinates() decided whether a tissue positions CSV has a header
from its file name alone. A headed file with the older
tissue_positions_list.csv name (common on GEO) was read with the header as
a data row, so every column became character and Read10X_Image() failed
with "cannot derive coordinates from non-numeric matrix". A headerless
file named tissue_positions.csv lost its first spot.

Closes satijalab#9240
@MMatinGerami
MMatinGerami force-pushed the fix/read10x-coordinates-header branch from 17e30cf to d825e11 Compare October 29, 2026 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error in .local(obj, ...) : cannot derive coordinates from non-numeric matrix

1 participant