使用python的rpy2进行调用R
import os
os.environ['R_HOME'] = "C:\\Users\\aohan\\Project\\iris\\software\\R-4.2.1"
if "R-4.2.1" not in os.environ['path']:
os.environ["PATH"] = "./software/R-4.2.1/bin/x64" + ";" + os.environ["PATH"]
from rpy2 import robjects
robjects.r('''library(org.Hs.eg.db)''')
执行 robjects.r('''library(org.Hs.eg.db)''') 这句时报错:
Traceback (most recent call last):
File "C:\app\python3.9\lib\asyncio\coroutines.py", line 124, in coro
res = func(*args, **kw)
File "C:\Users\aohan\Project\iris\flow-gui\test\rcode\test1.py", line 36, in test
robjects.r('''library(org.Hs.eg.db)''')
File "C:\app\python3.9\lib\site-packages\rpy2\robjects\__init__.py", line 459, in __call__
res = self.eval(p)
File "C:\app\python3.9\lib\site-packages\rpy2\robjects\functions.py", line 203, in __call__
return (super(SignatureTranslatedFunction, self)
File "C:\app\python3.9\lib\site-packages\rpy2\robjects\functions.py", line 126, in __call__
res = super(Function, self).__call__(*new_args, **new_kwargs)
File "C:\app\python3.9\lib\site-packages\rpy2\rinterface_lib\conversion.py", line 45, in _
cdata = function(*args, **kwargs)
File "C:\app\python3.9\lib\site-packages\rpy2\rinterface.py", line 815, in __call__
raise embedded.RRuntimeError(_rinterface._geterrmessage())
File "C:\app\python3.9\lib\site-packages\rpy2\rinterface_lib\_rinterface_capi.py", line 439, in _geterrmessage
res = _string_getitem(res, 0)
File "C:\app\python3.9\lib\site-packages\rpy2\rinterface_lib\_rinterface_capi.py", line 285, in _string_getitem
res = conversion._cchar_to_str(
File "C:\app\python3.9\lib\site-packages\rpy2\rinterface_lib\conversion.py", line 136, in _cchar_to_str
s = ffi.string(c).decode(encoding)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 33: invalid start byte
调试时发现,在"C:\app\python3.9\lib\site-packages\rpy2\rinterface_lib\conversion.py"文件中
这两句decode解码,默认encoding方式是"utf-8",但是当R语言返回的信息中,如这里它返回的是"不存在叫'org.Hs.eg.db'这个名字的程辑包",信息中有中文就导致编码不正常,如下修改即可解决:
def _cchar_to_str(c, encoding: str) -> str:
# TODO: use isString and installTrChar
try:
s = ffi.string(c).decode(encoding)
except Exception as e:
s = ffi.string(c).decode('GBK')
return s
def _cchar_to_str_with_maxlen(c, maxlen: int, encoding: str) -> str:
# TODO: use isString and installTrChar
try:
s = ffi.string(c, maxlen).decode(encoding)
except Exception as e:
s = ffi.string(c, maxlen).decode("GBK")
return s