# Convert Scanpy (h5ad) to Seurat (rds)

**URL:** https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457
**Category:** anndata
**Created:** [May 16, 2022, 10:29pm UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457 "2022-05-16T22:29:09Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![PEB](https://avatars.discourse-cdn.com/v4/letter/p/e480ec/32.png) [@PEB](https://discourse.scverse.org/u/PEB)
#### Post date: [May 16, 2022, 10:29pm UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/1 "2022-05-16T22:29:09Z")

</div>

Hi Everyone,

I am trying to convert my h5ad to a Seurat rds to run R-based pseudo time algorithms (monocle, slingshot, etc). However I keep running into errors on the commonly posted methods. Does anyone have any advice or experience on how to effectively read a scanpy h5ad in R?

Best,

peb

---

<div class="post-metadata">

### Author: ![Justin\_Hong](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/justin_hong/32/85_2.png) [@Justin\_Hong](https://discourse.scverse.org/u/Justin_Hong)
#### Post date: [May 16, 2022, 10:51pm UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/2 "2022-05-16T22:51:00Z")

</div>

I’ve had luck converting Seurat objects to AnnData objects in memory using the `sceasy::convertFormat` as demonstrated in our R tutorial here [Integrating datasets with scVI in R - scvi-tools](https://docs.scvi-tools.org/en/stable/tutorials/notebooks/scvi_in_R.html). You could try using this in the inverse direction using the `from` and `to` args.

P.S. Would be best to categorize this kind of question in the future under the “AnnData” tag.

---

<div class="post-metadata">

### Author: ![PEB](https://avatars.discourse-cdn.com/v4/letter/p/e480ec/32.png) [@PEB](https://discourse.scverse.org/u/PEB)
#### Post date: [May 16, 2022, 11:46pm UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/3 "2022-05-16T23:46:24Z")

</div>

Hi @Justin_Hong , thank you for the tip! I found a lot of good information from the link you provided.

I have ran into a error though, have you seen this one before?

```auto
ad <- anndata::read_h5ad('Results/celltype_assigned_raw.h5ad')
sceasy::convertFormat(ad, from="anndata", to="seurat", outFile='file.rds')

```

Error in path.expand(inFile): invalid ‘path’ argument  
Traceback:

1. sceasy::convertFormat(ad, from = “anndata”, to = “seurat”, outFile = “file.rds”)
2. func(obj, outFile = outFile, main\_layer = main\_layer, …)
3. path.expand(inFile)

R version 4.2.0 (2022-04-22)  
Platform: x86\_64-apple-darwin17.0 (64-bit)  
Running under: macOS Catalina 10.15.7

Matrix products: default  
BLAS: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRblas.0.dylib  
LAPACK: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRlapack.dylib

locale:  
[1] en\_US.UTF-8/en\_US.UTF-8/en\_US.UTF-8/C/en\_US.UTF-8/en\_US.UTF-8

attached base packages:  
[1] splines stats4 stats graphics grDevices utils datasets  
[8] methods base

other attached packages:  
[1] sp\_1.4-7 SeuratObject\_4.1.0  
[3] Seurat\_4.1.1 anndata\_0.7.5.3  
[5] sceasy\_0.0.6 reticulate\_1.25  
[7] MAST\_1.22.0 plyr\_1.8.7  
[9] clusterExperiment\_2.16.0 gam\_1.20.1  
[11] foreach\_1.5.2 monocle\_2.24.0  
[13] DDRTree\_0.1.5 irlba\_2.3.5  
[15] VGAM\_1.1-6 ggplot2\_3.3.6  
[17] Matrix\_1.4-1 slingshot\_2.4.0  
[19] TrajectoryUtils\_1.4.0 princurve\_2.1.6  
[21] RColorBrewer\_1.1-3 scran\_1.24.0  
[23] scuttle\_1.6.0 SingleCellExperiment\_1.18.0  
[25] SummarizedExperiment\_1.26.1 Biobase\_2.56.0  
[27] GenomicRanges\_1.48.0 GenomeInfoDb\_1.32.2  
[29] IRanges\_2.30.0 S4Vectors\_0.34.0  
[31] BiocGenerics\_0.42.0 MatrixGenerics\_1.8.0  
[33] matrixStats\_0.62.0 jsonlite\_1.8.0  
[35] formatR\_1.12

loaded via a namespace (and not attached):  
[1] pbdZMQ\_0.3-7 scattermore\_0.8  
[3] pkgmaker\_0.32.2 tidyr\_1.2.0  
[5] bit64\_4.0.5 DelayedArray\_0.22.0  
[7] rpart\_4.1.16 data.table\_1.14.2  
[9] KEGGREST\_1.36.0 RCurl\_1.98-1.6  
[11] doParallel\_1.0.17 generics\_0.1.2  
[13] ScaledMatrix\_1.4.0 leidenbase\_0.1.11  
[15] cowplot\_1.1.1 RSQLite\_2.2.14  
[17] RANN\_2.6.1 combinat\_0.0-8  
[19] future\_1.25.0 bit\_4.0.4  
[21] phylobase\_0.8.10 spatstat.data\_2.2-0  
[23] xml2\_1.3.3 httpuv\_1.6.5  
[25] assertthat\_0.2.1 viridis\_0.6.2  
[27] hms\_1.1.1 evaluate\_0.15  
[29] promises\_1.2.0.1 fansi\_1.0.3  
[31] progress\_1.2.2 igraph\_1.3.1  
[33] DBI\_1.1.2 htmlwidgets\_1.5.4  
[35] sparsesvd\_0.2 spatstat.geom\_2.4-0  
[37] purrr\_0.3.4 ellipsis\_0.3.2  
[39] dplyr\_1.0.9 annotate\_1.74.0  
[41] gridBase\_0.4-7 deldir\_1.0-6  
[43] locfdr\_1.1-8 sparseMatrixStats\_1.8.0  
[45] vctrs\_0.4.1 here\_1.0.1  
[47] ROCR\_1.0-11 abind\_1.4-5  
[49] cachem\_1.0.6 withr\_2.5.0  
[51] progressr\_0.10.0 sctransform\_0.3.3  
[53] prettyunits\_1.1.1 goftest\_1.2-3  
[55] softImpute\_1.4-1 cluster\_2.1.3  
[57] ape\_5.6-2 IRdisplay\_1.1  
[59] lazyeval\_0.2.2 crayon\_1.5.1  
[61] genefilter\_1.78.0 edgeR\_3.38.1  
[63] pkgconfig\_2.0.3 slam\_0.1-50  
[65] nlme\_3.1-157 rlang\_1.0.2  
[67] globals\_0.15.0 lifecycle\_1.0.1  
[69] miniUI\_0.1.1.1 registry\_0.5-1  
[71] rsvd\_1.0.5 rprojroot\_2.0.3  
[73] polyclip\_1.10-0 lmtest\_0.9-40  
[75] rngtools\_1.5.2 IRkernel\_1.3  
[77] Rhdf5lib\_1.18.0 zoo\_1.8-10  
[79] base64enc\_0.1-3 ggridges\_0.5.3  
[81] pheatmap\_1.0.12 png\_0.1-7  
[83] viridisLite\_0.4.0 bitops\_1.0-7  
[85] rncl\_0.8.6 KernSmooth\_2.23-20  
[87] rhdf5filters\_1.8.0 Biostrings\_2.64.0  
[89] blob\_1.2.3 DelayedMatrixStats\_1.18.0  
[91] stringr\_1.4.0 zinbwave\_1.18.0  
[93] spatstat.random\_2.2-0 parallelly\_1.31.1  
[95] beachmat\_2.12.0 scales\_1.2.0  
[97] memoise\_2.0.1 magrittr\_2.0.3  
[99] ica\_1.0-2 howmany\_0.3-1  
[101] zlibbioc\_1.42.0 compiler\_4.2.0  
[103] HSMMSingleCell\_1.16.0 dqrng\_0.3.0  
[105] fitdistrplus\_1.1-8 cli\_3.3.0  
[107] ade4\_1.7-19 XVector\_0.36.0  
[109] listenv\_0.8.0 patchwork\_1.1.1  
[111] pbapply\_1.5-0 mgcv\_1.8-40  
[113] MASS\_7.3-57 tidyselect\_1.1.2  
[115] stringi\_1.7.6 BiocSingular\_1.12.0  
[117] locfit\_1.5-9.5 ggrepel\_0.9.1  
[119] grid\_4.2.0 tools\_4.2.0  
[121] future.apply\_1.9.0 parallel\_4.2.0  
[123] uuid\_1.1-0 bluster\_1.6.0  
[125] RNeXML\_2.4.7 metapod\_1.4.0  
[127] gridExtra\_2.3 Rtsne\_0.16  
[129] digest\_0.6.29 rgeos\_0.5-9  
[131] shiny\_1.7.1 qlcMatrix\_0.9.7  
[133] Rcpp\_1.0.8.3 later\_1.3.0  
[135] RcppAnnoy\_0.0.19 httr\_1.4.3  
[137] AnnotationDbi\_1.58.0 kernlab\_0.9-30  
[139] colorspace\_2.0-3 tensor\_1.5  
[141] XML\_3.99-0.9 uwot\_0.1.11  
[143] statmod\_1.4.36 spatstat.utils\_2.3-1  
[145] plotly\_4.10.0 xtable\_1.8-4  
[147] R6\_2.5.1 pillar\_1.7.0  
[149] htmltools\_0.5.2 mime\_0.12  
[151] NMF\_0.24.0 glue\_1.6.2  
[153] fastmap\_1.1.0 BiocParallel\_1.30.2  
[155] BiocNeighbors\_1.14.0 codetools\_0.2-18  
[157] utf8\_1.2.2 spatstat.sparse\_2.1-1  
[159] lattice\_0.20-45 tibble\_3.1.7  
[161] leiden\_0.4.2 survival\_3.3-1  
[163] limma\_3.52.1 repr\_1.1.4  
[165] docopt\_0.7.1 fastICA\_1.2-3  
[167] munsell\_0.5.0 rhdf5\_2.40.0  
[169] GenomeInfoDbData\_1.2.8 iterators\_1.0.14  
[171] HDF5Array\_1.24.0 reshape2\_1.4.4  
[173] gtable\_0.3.0 spatstat.core\_2.4-2

---

<div class="post-metadata">

### Author: ![Justin\_Hong](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/justin_hong/32/85_2.png) [@Justin\_Hong](https://discourse.scverse.org/u/Justin_Hong)
#### Post date: [May 17, 2022, 12:04am UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/4 "2022-05-17T00:04:26Z")

</div>

> [@PEB](#):
>
> ```auto
> ad <- anndata::read_h5ad('Results/celltype_assigned_raw.h5ad')
> sceasy::convertFormat(ad, from="anndata", to="seurat", outFile='file.rds')
> 
> ```

Looking at their code, looks like when converting from AnnData they require you pass in an input filepath rather than a loaded object. Seems like it’s because they want to ensure the anndata package is loaded correctly for their code to work.

Try doing this instead

```auto
ad_path <- "Results/celltype_assigned_raw.h5ad"
sceasy::convertFormat(ad_path, from="anndata", to="seurat", outFile="file.rds")

```

---

<div class="post-metadata">

### Author: ![PEB](https://avatars.discourse-cdn.com/v4/letter/p/e480ec/32.png) [@PEB](https://discourse.scverse.org/u/PEB)
#### Post date: [May 17, 2022, 12:43am UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/5 "2022-05-17T00:43:18Z")

</div>

> [@PEB](#):
>
> `convertFormat`

Hey @Justin_Hong, thank you for catching that! You’re right, it needed a string as a parameter instead of an object 😄

Unfortunately it did not complete the conversion

```auto
ad_path <- "Results/celltype_assigned_hv.h5ad"
sceasy::convertFormat(ad_path, from="anndata", to="seurat", outFile="file.rds", use_seurat = FALSE, main_layer = "counts")

```

X → counts

Error in match(x, table, nomatch = 0L): ‘match’ requires vector arguments  
Traceback:

1. sceasy::convertFormat(ad\_path, from = “anndata”, to = “seurat”,  
. outFile = “file.rds”, use\_seurat = FALSE, main\_layer = “counts”)
2. func(obj, outFile = outFile, main\_layer = main\_layer, …)
3. sapply(embed\_names, function(x) reticulate::py\_to\_r(ad$obsm),  
. simplify = FALSE, USE.NAMES = TRUE)
4. lapply(X = X, FUN = FUN, …)
5. FUN(X[[i]], …)
6. reticulate::py\_to\_r(ad$obsm)
7. ad$obsm
8. `[.collections.abc.Mapping`(ad$obsm, x)
9. name %in% x$keys()

I found a similar unresolved error on GitHub: [Anndata to Seurat Object, Error in match · Issue #54 · cellgeni/sceasy · GitHub](https://github.com/cellgeni/sceasy/issues/54)  
I tried to gzip (as shared in Issue comments) but I can’t resolve the error as of yet.  
Thanks again for your help!

---

<div class="post-metadata">

### Author: ![gtca](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/gtca/32/1199_2.png) [@gtca](https://discourse.scverse.org/u/gtca)
#### Post date: [June 2, 2022, 1:39pm UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/6 "2022-06-02T13:39:51Z")

</div>

Hey @PEB,

You can also try using `ReadH5AD()` from [MuDataSeurat](https://github.com/PMBio/MuDataSeurat).  
There might be rough edges still but at least we can fix them quickly!

It is also a native R reader so no need for the Python environment and `reticulate`.

---

<div class="post-metadata">

### Author: ![PEB](https://avatars.discourse-cdn.com/v4/letter/p/e480ec/32.png) [@PEB](https://discourse.scverse.org/u/PEB)
#### Post date: [June 7, 2022, 12:42am UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/7 "2022-06-07T00:42:47Z")

</div>

Hey @gtca,

Thanks for reaching out and suggesting MuDataSeurat!  
Can you specify what kind of rough edges you’re referring to? Data loss?

I’ve been trying out MuDataSeurat and its been working pretty well. I do get some immediate errors.

```auto
Warning in read_layers_to_assay(h5) :
  Only a subset of mod//raw/X is loaded, variables (features) that are not present in mod//X are discarded.
Warning: Keys should be one or more alphanumeric characters followed by an underscore, setting key from rna to rna_
Warning: No columnames present in cell embeddings, setting to 'pca_1:50'
Warning: No columnames present in cell embeddings, setting to 'tsne_1:2'
Warning: No columnames present in cell embeddings, setting to 'umap_1:2'

```

However I do not think this impacted the process.  
I am having some errors with using the data object in pseudo time. I am not too sure if its the converted matrix or data on the algorithm.

In any case, thanks MuSeurat is much better than the other methods I’ve been testing.

Best,

PEB

---

<div class="post-metadata">

### Author: ![acaulier](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/acaulier/32/892_2.png) [@acaulier](https://discourse.scverse.org/u/acaulier)
#### Post date: [December 6, 2023, 3:53pm UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/8 "2023-12-06T15:53:12Z")

</div>

Hi @Justin_Hong,

I am trying to convert a rds object (JAN\_039) into anndata object following the R tutorial you recommended: [Integrating datasets with scVI in R — scvi-tools](https://docs.scvi-tools.org/en/1.0.1/tutorials/notebooks/scvi_in_R.html)  
But i keep getting an error from anndata package:

```auto
sceasy::convertFormat(JAN_039, from="seurat", to="anndata",
                       outFile='~/JAN_039_scenicplus/JAN_039.h5ad')

```

```auto
module 'anndata' has no attribute 'AnnData'Traceback:

1. sceasy::convertFormat(JAN_039, from = "seurat", to = "anndata", 
 . outFile = "~/JAN_039_scenicplus/JAN_039.h5ad")
2. func(obj, outFile = outFile, main_layer = main_layer, ...)
3. anndata$AnnData
4. `$.python.builtin.module`(anndata, "AnnData")
5. `$.python.builtin.object`(x, name)
6. py_get_attr_or_item(x, name, TRUE)
7. py_get_attr(x, name)
8. py_get_attr_impl(x, name, silent)

```

Any idea of what is going wrong in here?  
Thanks!

---

<div class="post-metadata">

### Author: ![bsierieb1](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/bsierieb1/32/775_2.png) [@bsierieb1](https://discourse.scverse.org/u/bsierieb1)
#### Post date: [September 24, 2024, 8:57pm UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/9 "2024-09-24T20:57:14Z")

</div>

the link to the tutorial is broken

---

<div class="post-metadata">

### Author: ![Justin\_Hong](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/justin_hong/32/85_2.png) [@Justin\_Hong](https://discourse.scverse.org/u/Justin_Hong)
#### Post date: [September 27, 2024, 5:23pm UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/10 "2024-09-27T17:23:59Z")

</div>

Sorry about that, here’s the updated link [Using Python in R with reticulate — scvi-tools](https://docs.scvi-tools.org/en/stable/tutorials/notebooks/quick_start/python_in_R.html)

---

<div class="post-metadata">

### Author: ![ori-kron-wis](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/ori-kron-wis/32/1099_2.png) [@ori-kron-wis](https://discourse.scverse.org/u/ori-kron-wis)
#### Post date: [November 6, 2025, 11:14am UTC](https://discourse.scverse.org/t/convert-scanpy-h5ad-to-seurat-rds/457/11 "2025-11-06T11:14:51Z")

</div>

If someone is looking, here is the updated link to scvi-tools R tutorials:

> **[Integrating datasets with scVI in R](https://docs.scvi-tools.org/en/latest/tutorials/notebooks/r/scvi_in_R.html)**
>
> In this tutorial, we go over how to use basic scvi-tools functionality in R. However, for more involved analyses, we suggest using scvi-tools from Python. Checkout the Scanpy\_in\_R tutorial for inst...

previous link was broken
