使用rpy2调用R的dea()时,如何处理RTYPES.NILSXP返回值?
解决rpy2调用R Benchmarking包dea()函数时dual/primal返回NULL的问题
在Python中使用rpy2调用R语言Benchmarking包的dea()函数时,部分返回值(如dual、primal等)会呈现RTYPES.NILSXP类型,无法像eff、lambda那样直接获取ndarray或int格式的数据。
环境配置代码
# imports import pandas as pd import rpy2 import rpy2.robjects as robjects import rpy2.robjects.packages as rpackages from rpy2.robjects.vectors import StrVector from rpy2.robjects.packages import importr utils = rpackages.importr('utils') utils.chooseCRANmirror(ind=1) # helps work with pd.DataFrame objects from rpy2.robjects import pandas2ri from rpy2.robjects.conversion import localconverter # import the R library into Python packnames = ('Benchmarking') utils.install_packages(StrVector(packnames)) Benchmarking = importr('Benchmarking') base = importr('base') data = pd.read_csv("path/to_data.csv") # call the function I want and store it in a variable with localconverter(robjects.default_converter + pandas2ri.converter): crs = Benchmarking.dea(data['Age'], data['CO2'], RTS='crs', ORIENTATION='in')
错误现象
调用dea()后,crs['eff']或crs['lambda']可正常返回ndarray:
crs # 输出: # {'eff': [1. 0.625 0.5 ], 'lambda': [[1. 0. 0. ] # [1.25 0. 0. ] # [1.5 0. 0. ]], 'objval': [1. 0.625 0.5 ], 'RTS': [1] "crs" # , 'primal': <rpy2.rinterface_lib.sexp.NULLType object at 0x00000220BCB0D1C0> [RTYPES.NILSXP], 'dual': <rpy2.rinterface_lib.sexp.NULLType object at 0x00000220BCB0D1C0> [RTYPES.NILSXP], 'ux': <rpy2.rinterface_lib.sexp.NULLType object at 0x00000220BCB0D1C0> [RTYPES.NILSXP], 'vy': <rpy2.rinterface_lib.sexp.NULLType object at 0x00000220BCB0D1C0> [RTYPES.NILSXP], 'gamma': function (x) .Primitive("gamma") # , 'ORIENTATION': [1] "in" # , 'TRANSPOSE': [1] FALSE # , 'param': <rpy2.rinterface_lib.sexp.NULLType object at 0x00000220BCB0D1C0> [RTYPES.NILSXP], }
但提取crs['dual']等返回值时,仅得到NULL对象:
crs['dual'] # 输出: # <rpy2.rinterface_lib.sexp.NULLType object at 0x00000220BCB0D1C0> [RTYPES.NILSXP]
错误尝试及报错
尝试用fetch()方法加载该对象时,报错:
rpy2.robjects.packages.PackageData.fetch(crs['dual']) # 报错: # TypeError: PackageData.fetch() missing 1 required positional argument: 'name'
传入名称参数后仍报错:
rpy2.robjects.packages.PackageData.fetch(r_from_df_crs['dual'], 'dual') # 报错: # AttributeError: 'NULLType' object has no attribute '_datasets'
尝试用rpackages.data()转换对象也报错:
my_crs = rpackages.data(crs) # 报错: # AttributeError: 'OrdDict' object has no attribute '__rdata__'
解决方案
问题根源是调用dea()函数时未传入SLACK=True和DUAL=True参数,导致dual、primal等相关结果默认返回NULL值。修改后的调用代码如下:
with localconverter(robjects.default_converter + pandas2ri.converter): crs = Benchmarking.dea(data['Age'], data['CO2'], RTS='crs', ORIENTATION='in', SLACK=True, DUAL=True)
添加这两个参数后,dual、primal等返回值会正常生成,可像eff、lambda一样转换为Python可直接使用的数据格式。
内容的提问来源于stack exchange,提问作者Sully H
相关产品推荐
相关产品推荐

