Jupyter重复运行rpy2代码报错:未定义SexpClosure的rpy2py转换
修复Jupyter中rpy2重复运行报错的方案
问题原因
rpy2 3.x版本在Jupyter交互式环境中,重复执行robjects.r['smooth.spline']这类提取R函数的操作时,会触发转换上下文冲突,导致无法将R的SexpClosure对象转换为Python可调用对象,进而抛出NotImplementedError。
修复方案1:直接调用R函数,避免重复提取
不需要单独将R函数赋值给Python变量,直接通过robjects.r调用函数,绕过重复提取导致的转换问题:
import numpy as np import rpy2.robjects as robjects x = np.linspace(0, 1, num = 11, endpoint=True) y = np.array([-1,1,1, -1,1,0, .5,.5,.4, .5, -1]) r_x = robjects.FloatVector(x) r_y = robjects.FloatVector(y) # 直接调用R的smooth.spline,不再单独提取赋值 spline_xy = robjects.r.smooth.spline(x=r_x, y=r_y) print('x =', x) print('ysplined =', np.array(robjects.r.predict(spline_xy, robjects.FloatVector(x)).rx2('y')))
修复方案2:提前提取函数到全局作用域
将R函数的提取操作放在仅执行一次的位置(比如单独单元格,或当前单元格最顶部),避免重复提取:
# 此单元格仅需运行一次 import numpy as np import rpy2.robjects as robjects # 一次性提取R函数到全局变量 r_smooth_spline = robjects.r['smooth.spline'] r_predict = robjects.r['predict']
重复运行的单元格中使用全局变量:
x = np.linspace(0, 1, num = 11, endpoint=True) y = np.array([-1,1,1, -1,1,0, .5,.5,.4, .5, -1]) r_x = robjects.FloatVector(x) r_y = robjects.FloatVector(y) spline_xy = r_smooth_spline(x=r_x, y=r_y) print('x =', x) print('ysplined =', np.array(r_predict(spline_xy, robjects.FloatVector(x)).rx2('y')))
修复方案3:显式使用转换上下文
通过localconverter强制指定转换规则,确保每次运行时转换正常:
import numpy as np import rpy2.robjects as robjects from rpy2.robjects import default_converter from rpy2.robjects.conversion import localconverter x = np.linspace(0, 1, num = 11, endpoint=True) y = np.array([-1,1,1, -1,1,0, .5,.5,.4, .5, -1]) r_x = robjects.FloatVector(x) r_y = robjects.FloatVector(y) # 显式使用默认转换器上下文 with localconverter(default_converter): r_smooth_spline = robjects.r['smooth.spline'] spline_xy = r_smooth_spline(x=r_x, y=r_y) predict_result = robjects.r['predict'](spline_xy, robjects.FloatVector(x)) y_splined = np.array(predict_result.rx2('y')) print('x =', x) print('ysplined =', y_splined)
方案4:升级rpy2版本
rpy2 3.5.5存在交互式环境的转换bug,升级到最新稳定版(如3.5.11及以上)可修复此类问题,执行命令:
pip install --upgrade rpy2
内容的提问来源于stack exchange,提问作者Jakob
相关产品推荐
相关产品推荐

