Thank you for your interest in contributing to anndataR! Contributions of all kinds are welcome, including bug reports, documentation improvements and code.
Reporting issues and asking questions
Please use the issue tracker and pick the matching template.
Contributing code
- Open an issue first for anything larger than a small fix
- Fork the repository and create a branch from
devel - Make your changes, following the conventions below
- Open a pull request against
develand fill in the PR template
Conventions
- Format code with Air (
air format .) and vignettes withstyler::style_dir("vignettes"), then check withlintr::lint_package() - Document functions with roxygen2 and regenerate the man pages with
devtools::document(), using the roxygen2 version pinned inDESCRIPTION(Config/roxygen2/version) - Add or update tests in
tests/testthat/ - Add or update examples in the vignettes where relevant
- Check that new behaviour matches Python anndata where applicable (see the roundtrip tests)
- Keep lines to 120 characters or fewer (use
paste()to wrap long strings in tests) - Use
check_requires()before using an optional package and add a matching skip in tests - Use
clifor messages and errors
Running checks
devtools::test()
devtools::test(filter = "roundtrip-X") # Run a single test file
devtools::check()
BiocCheck::BiocCheck()Some tests require Python anndata and are skipped if it is not available. Set ANNDATAR_TEST_REQUIRE_PYTHON=true to make them fail instead.
Testing
- Use the
skip_if_no_*()helpers intests/testthat/for tests needing optional dependencies (Python anndata, dummy_anndata, zarr,h5diff) - Use
generate_dataset()to create mock data with different matrix types and edge cases - Add a roundtrip test (
test-roundtrip-*.R) when changing anything that affects compatibility with Python - Verify HDF5 changes against Python output with
h5diff
Package design
See the software design article for details. Some key points to be aware of:
-
AnnData classes:
AbstractAnnDatais the base class forInMemoryAnnData,HDF5AnnData,ZarrAnnData,ReticulateAnnDataandAnnDataView. Changes to the interface usually need to be made in all of them. -
Names are stored separately:
obs_namesandvar_namesare stored apart fromobs/var, and dimnames are added when data is accessed. Internal code should useadata$obs_namesandadata$var_namesrather thanrownames(adata$obs)orcolnames(adata$X). -
Views are read-only:
AnnDataView(returned byadata[i, j]) subsets lazily and can’t be modified. Convert it with one of the$as_*AnnData()methods first when needed. -
Validation: setters use the validation helpers in
AbstractAnnData. Update these if you change the rules for a slot. -
Conversion:
from_*()functions convert other formats to AnnData andas_*()functions convert AnnData to other formats. Update both when adding a conversion feature. -
Python differences: Python AnnData allows duplicate names and distinguishes
Nonefrom an empty dict, which R doesn’t. Known issues are tracked ininst/known_issues.yaml.
Package authors
New contributors are welcome to add themselves to the package authors in DESCRIPTION. Add a person() entry with the ctb role in your pull request, including your ORCID and GitHub username in the comment field.
Code of conduct
Please be respectful and constructive in all interactions. This project follows the scverse code of conduct.