Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversion 'py2rpy' not defined for objects of type '<class 'numpy.ndarray'>' #50

Closed
satellite119 opened this issue Aug 10, 2020 · 25 comments · Fixed by #95
Closed

Conversion 'py2rpy' not defined for objects of type '<class 'numpy.ndarray'>' #50

satellite119 opened this issue Aug 10, 2020 · 25 comments · Fixed by #95
Labels
bug Something isn't working

Comments

@satellite119
Copy link

satellite119 commented Aug 10, 2020

Hello, I encountered a problem when I tried to run Slingshot following the scripts for "Current best-practices in single-cell RNA-seq: a tutorial".

%%R -i adata

#Plot 1
colour_map = brewer.pal(20,'Set1')
par(xpd=TRUE)
par(mar=c(4.5,5.5,2,7))
plot(reducedDims(adata)$PCA[,1], reducedDims(adata)$PCA[,2], col=colour_map[colData(adata)$louvain_r0.8], bty='L', xlab='PC1', ylab='PC2')
legend(x=12, y=12, legend=unique(colData(adata)$louvain_r0.8), fill=colour_map[as.integer(unique(colData(adata)$louvain_r0.8))])

print("1:")
adata_start <- slingshot(adata, clusterLabels = 'louvain_r0.8', reducedDim = 'PCA', start.clus='qHSC')
print(SlingshotDataSet(adata_start))

Then the problem is

NotImplementedError                       Traceback (most recent call last)
<ipython-input-49-f2b65708de9e> in <module>
----> 1 get_ipython().run_cell_magic('R', '-i adata', '\n#Plot 1\ncolour_map = brewer.pal(20,\'Set1\')\npar(xpd=TRUE)\npar(mar=c(4.5,5.5,2,7))\nplot(reducedDims(adata)$PCA[,1], reducedDims(adata)$PCA[,2], col=colour_map[colData(adata)$louvain_r0.8], bty=\'L\', xlab=\'PC1\', ylab=\'PC2\')\nlegend(x=12, y=12, legend=unique(colData(adata)$louvain_r0.8), fill=colour_map[as.integer(unique(colData(adata)$louvain_r0.8))])\n\nprint("1:")\nadata_start <- slingshot(adata, clusterLabels = \'louvain_r0.8\', reducedDim = \'PCA\', start.clus=\'qHSC\')\nprint(SlingshotDataSet(adata_start))\n')

~/.conda/envs/scanpy/lib/python3.8/site-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
   2369             with self.builtin_trap:
   2370                 args = (magic_arg_s, cell)
-> 2371                 result = fn(*args, **kwargs)
   2372             return result
   2373 

<decorator-gen-130> in R(self, line, cell, local_ns)

~/.conda/envs/scanpy/lib/python3.8/site-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
    185     # but it's overkill for just that one bit of state.
    186     def magic_deco(arg):
--> 187         call = lambda f, *a, **k: f(*a, **k)
    188 
    189         if callable(arg):

~/.conda/envs/scanpy/lib/python3.8/site-packages/rpy2/ipython/rmagic.py in R(self, line, cell, local_ns)
    735                         raise NameError("name '%s' is not defined" % input)
    736                 with localconverter(converter) as cv:
--> 737                     ro.r.assign(input, val)
    738 
    739         if args.display:

~/.conda/envs/scanpy/lib/python3.8/site-packages/rpy2/robjects/functions.py in __call__(self, *args, **kwargs)
    195                 v = kwargs.pop(k)
    196                 kwargs[r_k] = v
--> 197         return (super(SignatureTranslatedFunction, self)
    198                 .__call__(*args, **kwargs))
    199 

~/.conda/envs/scanpy/lib/python3.8/site-packages/rpy2/robjects/functions.py in __call__(self, *args, **kwargs)
    115 
    116     def __call__(self, *args, **kwargs):
--> 117         new_args = [conversion.py2rpy(a) for a in args]
    118         new_kwargs = {}
    119         for k, v in kwargs.items():

~/.conda/envs/scanpy/lib/python3.8/site-packages/rpy2/robjects/functions.py in <listcomp>(.0)
    115 
    116     def __call__(self, *args, **kwargs):
--> 117         new_args = [conversion.py2rpy(a) for a in args]
    118         new_kwargs = {}
    119         for k, v in kwargs.items():

~/.conda/envs/scanpy/lib/python3.8/functools.py in wrapper(*args, **kw)
    873                             '1 positional argument')
    874 
--> 875         return dispatch(args[0].__class__)(*args, **kw)
    876 
    877     funcname = getattr(func, '__name__', 'singledispatch function')

~/.conda/envs/scanpy/lib/python3.8/site-packages/anndata2ri/py2r.py in py2rpy_anndata(obj)
     69         # Convert everything we know
     70         with localconverter(full_converter() + dict_converter):
---> 71             metadata = ListVector(obj.uns.items())
     72 
     73         rd_args = {conv_name.scanpy2sce(k): mat_converter.py2rpy(obj.obsm[k]) for k in obj.obsm.keys()}

~/.conda/envs/scanpy/lib/python3.8/site-packages/rpy2/robjects/vectors.py in __init__(self, tlist)
    639                 raise ValueError('tlist should have a /method/ __iter__ '
    640                                  '(not an attribute)')
--> 641             kv = [(str(k), conversion.py2rpy(v)) for k, v in tlist]
    642             kv = tuple(kv)
    643             df = baseenv_ri.find("list").rcall(kv, globalenv_ri)

~/.conda/envs/scanpy/lib/python3.8/site-packages/rpy2/robjects/vectors.py in <listcomp>(.0)
    639                 raise ValueError('tlist should have a /method/ __iter__ '
    640                                  '(not an attribute)')
--> 641             kv = [(str(k), conversion.py2rpy(v)) for k, v in tlist]
    642             kv = tuple(kv)
    643             df = baseenv_ri.find("list").rcall(kv, globalenv_ri)

~/.conda/envs/scanpy/lib/python3.8/functools.py in wrapper(*args, **kw)
    873                             '1 positional argument')
    874 
--> 875         return dispatch(args[0].__class__)(*args, **kw)
    876 
    877     funcname = getattr(func, '__name__', 'singledispatch function')

~/.conda/envs/scanpy/lib/python3.8/site-packages/rpy2/robjects/conversion.py in _py2rpy(obj)
    170     objects.
    171     """
--> 172     raise NotImplementedError(
    173         "Conversion 'py2rpy' not defined for objects of type '%s'" %
    174         str(type(obj))

NotImplementedError: Conversion 'py2rpy' not defined for objects of type '<class 'numpy.ndarray'>'

Do you know how to solve this problem?
Thank you

@flying-sheep
Copy link
Collaborator

Please check out the README section Usage from Jupyter

@flying-sheep
Copy link
Collaborator

flying-sheep commented Aug 14, 2020

Hmm, wait. If %%R -i adata worked, then you have already activated everything correctly.

I wonder why it 1. tries to convert anything from Python to R and 2. doesn’t know about ndarray…

Do you have the newest anndata2ri version installed?

@flying-sheep flying-sheep reopened this Aug 14, 2020
@flying-sheep flying-sheep added the needs info The reported information is incomplete label Aug 14, 2020
@satellite119
Copy link
Author

satellite119 commented Aug 14, 2020

Hmm, wait. If %%R -i adata worked, then you have already activated everything correctly.

I wonder why it 1. tries to convert anything from Python to R and 2. doesn’t know about ndarray…

Do you have the newest anndata2ri version installed?

Yes, the newest anndata2ri version is already installed. I typed below:

rpy2.rinterface_lib.callbacks.logger.setLevel(logging.ERROR)
pandas2ri.activate()
anndata2ri.activate()
%load_ext rpy2.ipython
plt.rcParams['figure.figsize']=(8,8) #rescale figures
sc.settings.verbosity = 3
sc.set_figure_params(dpi=130, dpi_save=300)
sc.logging.print_versions()

Then I get:
scanpy==1.5.1 anndata==0.7.4 umap==0.4.6 numpy==1.19.0 scipy==1.5.1 pandas==1.0.5 scikit-learn==0.23.1 statsmodels==0.11.1 python-igraph==0.8.2 louvain==0.6.1

@flying-sheep
Copy link
Collaborator

flying-sheep commented Aug 19, 2020

I need data to reproduce this with…

Please create code that uses a built-in scanpy dataset (or no dataset), takes a short time to run, and still reproduces this.

@scottgigante
Copy link
Contributor

This is reproducible and occurs if numpy2ri.activate() is called after anndata2ri.activate().

Minimal code sample

import scanpy as sc
import rpy2.robjects as ro
import rpy2.robjects.numpy2ri
import anndata2ri

anndata2ri.activate()
rpy2.robjects.numpy2ri.activate()

pbmc = sc.datasets.pbmc68k_reduced()
ro.globalenv['sce'] = pbmc
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/scottgigante/.local/lib/python3.6/site-packages/rpy2/robjects/environments.py", line 32, in __setitem__
    robj = conversion.converter.py2rpy(value)
  File "/usr/lib/python3.6/functools.py", line 807, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
  File "/home/scottgigante/.local/lib/python3.6/site-packages/anndata2ri/py2r.py", line 72, in py2rpy_anndata
    metadata = ListVector(obj.uns.items())
  File "/home/scottgigante/.local/lib/python3.6/site-packages/rpy2/robjects/vectors.py", line 641, in __init__
    kv = [(str(k), conversion.py2rpy(v)) for k, v in tlist]
  File "/home/scottgigante/.local/lib/python3.6/site-packages/rpy2/robjects/vectors.py", line 641, in <listcomp>
    kv = [(str(k), conversion.py2rpy(v)) for k, v in tlist]
  File "/usr/lib/python3.6/functools.py", line 807, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
  File "/home/scottgigante/.local/lib/python3.6/site-packages/rpy2/robjects/conversion.py", line 174, in _py2rpy
    str(type(obj))
NotImplementedError: Conversion 'py2rpy' not defined for objects of type '<class 'numpy.ndarray'>'

Versions

>>> sc.logging.print_versions()
scanpy==1.4.6 anndata==0.7.3 umap==0.4.6 numpy==1.19.1 scipy==1.5.2 pandas==1.0.5 scikit-learn==0.23.1 statsmodels==0.11.1 python-igraph==0.8.2 louvain==0.6.0
>>> anndata2ri.__version__
'1.0.5.dev2+ea266ab'
>>> rpy2.__version__
'3.3.6'
>>> sys.version_info
sys.version_info(major=3, minor=6, micro=9, releaselevel='final', serial=0)

@flying-sheep
Copy link
Collaborator

Ah! Well, I have absolutely no idea in what way that breaks things and how I can prevent it.

For the time being, “don’t do that” might be a good fix.

Thank you for investigating! ☺️

@scottgigante
Copy link
Contributor

Looks like the short answer is stop using .activate. See https://github.com/rpy2/rpy2/blob/master/rpy2/robjects/numpy2ri.py#L182

@flying-sheep
Copy link
Collaborator

flying-sheep commented Oct 30, 2020

Well, the problem is that IPython’s R magic only works with the global converter, no?

@scottgigante
Copy link
Contributor

Right, so for that specific application the solution is to activate numpy2ri before anndata2ri, but for all other purposes a shift to local converters is probably wise.

@kehey
Copy link

kehey commented Nov 21, 2020

Well, the problem is that IPython’s R magic only works with the global converter, no?

@flying-sheep: There seems to be a parameter in %%R allowing to specify the converter called --converter. See https://rpy2.github.io/doc/latest/html/interactive.html#rmagic

I'm having trouble getting it to work but I have no idea how all this conversion stuff works so maybe I'm doing something stupid. If anyone with better knowledge on the rpy2 local convertors could maybe check this out, that would be great.

I have access to the localconverter:

in Jupyter, running anndata2ri.converter in a cell outputs <rpy2.robjects.conversion.Converter at 0x7fa923c96d00> but when I try the command

%%R -i adata_test --converter anndata2ri.converter, I get the error NameError: name 'anndata2ri.converter' is not defined

So I'm missing how to make %%R see the local converter so it can be specified. But as I said, rpy2 and its convertors are beyond me.

@flying-sheep
Copy link
Collaborator

Maybe it just supports named variables, because it does something like globals()[converter_name]?

Try from anndata2ri import converter and using it like that.

@Kovenda
Copy link

Kovenda commented Jul 18, 2022

I had the same error while attempting a conversion of a pandas DataFrame to and an r DataFrame:
Here was the fix:
Instead of simply saying:

pandas_df_2_r = ro.conversion.py2rpy(pandas_df)

This page suggested this instead:

with localconverter(ro.default_converter + pandas2ri.converter):
  pandas_df_2_r = ro.conversion.py2rpy(pandas_df)

And it worked.

@rimelof
Copy link

rimelof commented Jul 28, 2022

Hi @flying-sheep, @scottgigante, and @satellite119,

Sorry to ping everyone, but I do not understand why this is closed and what is the solution. I am having the same error as the original post. I tried activating numpy2ri before anndata2ri, or %%R -i mapped_spatial --converter anndata2ri.converter and also from anndata2ri import converter, with the respective errors described above.

Can someone point me to the right direction?
Thanks!

@flying-sheep
Copy link
Collaborator

Did you try what @Kovenda proposed right above your comment?

@rimelof
Copy link

rimelof commented Jul 29, 2022

Hi @flying-sheep, thank you for replying.

Yes, I tried. I first imported these

import rpy2.robjects as ro
from rpy2.robjects.conversion import localconverter
from rpy2.robjects import pandas2ri

and

with localconverter(ro.default_converter + pandas2ri.converter):
  rdata = ro.conversion.py2rpy(adata)

results in

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Input In [10], in <cell line: 1>()
      1 with localconverter(ro.default_converter + pandas2ri.converter):
----> 2   rdata = ro.conversion.py2rpy(adata)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/rpy2/robjects/conversion.py:365, in _deprecated_py2rpy(obj)
    362 def _deprecated_py2rpy(
    363         obj: Any
    364 ) -> _rinterface_capi.SupportsSEXP:
--> 365     return converter_ctx.get('converter').py2rpy(obj)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/rpy2/robjects/conversion.py:240, in _py2rpy(obj)
    238 if isinstance(obj, _rinterface_capi.SupportsSEXP):
    239     return obj
--> 240 raise NotImplementedError(
    241     "Conversion 'py2rpy' not defined for objects of type '%s'" %
    242     str(type(obj))
    243 )

NotImplementedError: Conversion 'py2rpy' not defined for objects of type '<class 'anndata._core.anndata.AnnData'>'

I also tried

with localconverter(ro.default_converter + pandas2ri.converter + anndata2ri.converter):
  rdata = ro.conversion.py2rpy(adata)

with the error

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Input In [11], in <cell line: 1>()
      1 with localconverter(ro.default_converter + pandas2ri.converter + anndata2ri.converter):
----> 2   rdata = ro.conversion.py2rpy(adata)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/rpy2/robjects/conversion.py:365, in _deprecated_py2rpy(obj)
    362 def _deprecated_py2rpy(
    363         obj: Any
    364 ) -> _rinterface_capi.SupportsSEXP:
--> 365     return converter_ctx.get('converter').py2rpy(obj)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/anndata2ri/py2r.py:73, in py2rpy_anndata(obj)
     70 with localconverter(full_converter() + dict_converter):
     71     metadata = ListVector(obj.uns.items())
---> 73 rd_args = {conv_name.scanpy2sce(k): mat_converter.py2rpy(obj.obsm[k]) for k in obj.obsm.keys()}
     74 reduced_dims = s4v.SimpleList(**rd_args)
     76 return sce.SingleCellExperiment(
     77     assays=assays, rowData=row_data, colData=col_data, metadata=metadata, reducedDims=reduced_dims
     78 )

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/anndata2ri/py2r.py:73, in <dictcomp>(.0)
     70 with localconverter(full_converter() + dict_converter):
     71     metadata = ListVector(obj.uns.items())
---> 73 rd_args = {conv_name.scanpy2sce(k): mat_converter.py2rpy(obj.obsm[k]) for k in obj.obsm.keys()}
     74 reduced_dims = s4v.SimpleList(**rd_args)
     76 return sce.SingleCellExperiment(
     77     assays=assays, rowData=row_data, colData=col_data, metadata=metadata, reducedDims=reduced_dims
     78 )

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/rpy2/robjects/numpy2ri.py:129, in nonnumpy2rpy(obj)
    127 if not isinstance(obj, numpy.ndarray) and hasattr(obj, '__array__'):
    128     obj = obj.__array__()
--> 129     return ro.default_converter.py2rpy(obj)
    130 elif original_converter is None:
    131     # This means that the conversion module was not "activated".
    132     # For now, go with the default_converter.
    133     # TODO: the conversion system needs an overhaul badly.
    134     return ro.default_converter.py2rpy(obj)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/rpy2/robjects/conversion.py:240, in _py2rpy(obj)
    238 if isinstance(obj, _rinterface_capi.SupportsSEXP):
    239     return obj
--> 240 raise NotImplementedError(
    241     "Conversion 'py2rpy' not defined for objects of type '%s'" %
    242     str(type(obj))
    243 )

NotImplementedError: Conversion 'py2rpy' not defined for objects of type '<class 'numpy.ndarray'>'

It might be my inexperience with converters, but I got stuck at this point.

Thanks!

@m21camby
Copy link

Hi, I solved the issue NotImplementedError: Conversion 'py2rpy' not defined for objects of type '<class 'numpy.ndarray'>' by downgrade packages:
rpy2==3.4.2
anndata2ri==1.0.6

Give it a try.

@rimelof
Copy link

rimelof commented Jul 29, 2022

I just downgraded them, problem persists.

@flying-sheep
Copy link
Collaborator

What if you try them all?

with localconverter(ro.default_converter + numpy2ri.converter + pandas2ri.converter + anndata2ri.converter):
    sce = ro.conversion.py2rpy(adata)

@rimelof
Copy link

rimelof commented Jul 29, 2022

Importing them all with

import rpy2.robjects as ro
from rpy2.robjects.conversion import localconverter
from rpy2.robjects import pandas2ri
import rpy2.robjects.numpy2ri as numpy2ri

and

with localconverter(ro.default_converter + numpy2ri.converter + pandas2ri.converter + anndata2ri.converter):
  rdata = ro.conversion.py2rpy(adata)

results in

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Input In [8], in <cell line: 1>()
      1 with localconverter(ro.default_converter + numpy2ri.converter + pandas2ri.converter + anndata2ri.converter):
----> 2   rdata = ro.conversion.py2rpy(adata)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/anndata2ri/py2r.py:74, in py2rpy_anndata(obj)
     71 with localconverter(full_converter() + dict_converter):
     72     metadata = ListVector(obj.uns.items())
---> 74 rd_args = {conv_name.scanpy2sce(k): mat_converter.py2rpy(obj.obsm[k]) for k in obj.obsm.keys()}
     75 reduced_dims = s4v.SimpleList(**rd_args)
     77 return sce.SingleCellExperiment(
     78     assays=assays, rowData=row_data, colData=col_data, metadata=metadata, reducedDims=reduced_dims
     79 )

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/anndata2ri/py2r.py:74, in <dictcomp>(.0)
     71 with localconverter(full_converter() + dict_converter):
     72     metadata = ListVector(obj.uns.items())
---> 74 rd_args = {conv_name.scanpy2sce(k): mat_converter.py2rpy(obj.obsm[k]) for k in obj.obsm.keys()}
     75 reduced_dims = s4v.SimpleList(**rd_args)
     77 return sce.SingleCellExperiment(
     78     assays=assays, rowData=row_data, colData=col_data, metadata=metadata, reducedDims=reduced_dims
     79 )

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/rpy2/robjects/numpy2ri.py:128, in nonnumpy2rpy(obj)
    126 if not isinstance(obj, numpy.ndarray) and hasattr(obj, '__array__'):
    127     obj = obj.__array__()
--> 128     return ro.default_converter.py2rpy(obj)
    129 elif original_converter is None:
    130     # This means that the conversion module was not "activated".
    131     # For now, go with the default_converter.
    132     # TODO: the conversion system needs an overhaul badly.
    133     return ro.default_converter.py2rpy(obj)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/functools.py:889, in singledispatch.<locals>.wrapper(*args, **kw)
    885 if not args:
    886     raise TypeError(f'{funcname} requires at least '
    887                     '1 positional argument')
--> 889 return dispatch(args[0].__class__)(*args, **kw)

File ~/miniconda3/envs/anndata2ri_pip/lib/python3.10/site-packages/rpy2/robjects/conversion.py:188, in _py2rpy(obj)
    186 if isinstance(obj, _rinterface_capi.SupportsSEXP):
    187     return obj
--> 188 raise NotImplementedError(
    189     "Conversion 'py2rpy' not defined for objects of type '%s'" %
    190     str(type(obj))
    191 )

NotImplementedError: Conversion 'py2rpy' not defined for objects of type '<class 'numpy.ndarray'>'

@serjisa
Copy link

serjisa commented Oct 24, 2022

Hi @flying-sheep, @rimelof.

Sometimes I have the same issue, and it seems, that in particular cases the porblem in adata.obsm. Here is an example.

adata_tmp = sc.AnnData(
    X=adata.X,
    obs=adata.obs,
    var=adata.var,
    uns=adata.uns,
    obsm=adata.obsm,
    obsp=adata.obsp,
    layers=adata.layers,
)
ro.globalenv["adata_tmp"] = adata_tmp

results in

...
NotImplementedError: Conversion 'py2rpy' not defined for objects of type '<class 'numpy.ndarray'>'

But it works if adata_tmp doesn't include adata.obsm.

adata_tmp = sc.AnnData(
    X=adata.X,
    obs=adata.obs,
    var=adata.var,
    uns=adata.uns,
    obsp=adata.obsp,
    layers=adata.layers,
)
ro.globalenv["adata_tmp"] = adata_tmp

works fine.

I found out that it was due to adata.obsm['mlm_estimate'] (output of Decoupler package), there was a pandas DataFrame, not np.array.

@flying-sheep
Copy link
Collaborator

Ha, that’s an actual lead!

@flying-sheep flying-sheep reopened this Oct 26, 2022
@flying-sheep
Copy link
Collaborator

flying-sheep commented Oct 26, 2022

Well, I still can’t reproduce this. Can you modify the below minimal reproducer until it actually reproduces the problem?

I obviously can’t go from your code since you didn’t define what adata is.

import rpy2
import rpy2.robjects as ro
from rpy2.robjects.conversion import localconverter

import numpy as np
import anndata2ri
from anndata import AnnData

with localconverter(anndata2ri.converter):
    ro.globalenv["adata_tmp"] = AnnData(
        X=np.array([[1,2],[3,4]]),
        obsm=dict(a=np.array([[5,6,7],[8,9,0]])),
    )

@serjisa
Copy link

serjisa commented Oct 26, 2022

@flying-sheep
Copy link
Collaborator

flying-sheep commented Oct 26, 2022

Thank you that’s great! This is the minimal reproducible example I was looking for:

import pandas as pd
import numpy as np
from anndata import AnnData

import rpy2.robjects as ro
from rpy2.robjects.conversion import localconverter
import anndata2ri

adata_obsm_pd = AnnData(
    X=np.array([[1,2],[3,4]]),
    obs=dict(obs_names=['a','b']),
    obsm=dict(a=pd.DataFrame([[5,6,7],[8,9,0]], index=['a','b'])),
)

with localconverter(anndata2ri.converter):
    ro.globalenv["adata_obsm_pd"] = adata_obsm_pd

@sfederow-velia
Copy link

Two additional tips for anyone who makes it to this thread and finds a dead end.

  1. Ensure all of the dtypes on any pandas dataframe within your anndata object are NOT object type. In my case this was casting multiple columns in adata.obs to category type
  2. Cast any numpy.ndarray objects within your anndata object to scipy.sparse.csc_matrix. In my case this was adata.X and adata.X_pca after running PCA.

After doing that I was able to pull the adata object into R without any issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants