在rpy2错误中调用R函数 - "参数丢失"

时间:2016-02-11 07:07:33

标签: python r rpy2

我在Python中使用rpy2包时遇到了一些问题。 实际上,我试图通过传递一些参数来调用一个名为upliftRF的函数(库中的#34; uplift"在R中)。 正如https://cran.r-project.org/web/packages/uplift/uplift.pdf第27页所述,函数的一个参数可以是x或一个公式,它描述了基于数据框拟合的模型("参数中的数据"参数)。 在R中执行第29页的代码时,一切都在运行,没有任何问题。但是,我在rpy2中遇到了一些问题。这是我的代码:

import pandas.rpy.common as com
from rpy2.robjects.packages import importr
from rpy2.robjects import pandas2ri
uplift = importr('uplift')
kwargs = {'n': 1000, 'p' : 20, 'rho' : 0, 'sigma' : np.sqrt(2), 'beta.den': 4}
dd = uplift.sim_pte(**kwargs)
ddPD = pandas2ri.ri2py(dd)
ddPD['treat'] = [1 if x==1 else 0 for x in ddPD['treat']]
dd = com.convert_to_r_dataframe(ddPD) 
kwargs2 = {'formula':'y ~ X1 + X2 + X3 + X4 + X5 + X6 + trt(treat)',
         'mtry':3,'ntree':200,'split_method':'KL','minsplit':200,'data':dd}

fit1 = uplift.upliftRF(**kwargs2)

然后,我收到了这个错误:

RRuntimeError: Error in is.data.frame(x) : argument "x" is missing, with no default

然而," x"不是函数的必需参数。

我猜对于任何其他具有一个非强制性参数的R函数,该错误都是相同的。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

import pandas.rpy.common as com
from rpy2.robjects.packages import importr
from rpy2.robjects import pandas2ri
uplift = importr('uplift')

接下来,您应该能够使用最常用的方式来调用Python函数,因为importr正在“翻译”命名参数 将R函数定义为语法上有效的Python名称。

dd = uplift.sim_pte(n = 1000, p = 20, rho = 0,
                    sigma = np.sqrt(2), beta_den = 4)

此时您似乎有一个R data.frame。转到pandas添加一个列,然后回到R,肯定是可能的:

ddPD = pandas2ri.ri2py(dd) 
ddPD['treat'] = [1 if x==1 else 0 for x in ddPD['treat']]
dd = com.convert_to_r_dataframe(ddPD)

但是,除非有充分的理由,否则我建议在pandasrpy2之间穿梭时坚持使用一种转换方案。唯一的那个 在pandas中定义或在rpy2中定义的一致性 可能是测试较少。错误RRuntimeError: Error: $ operator is invalid for atomic vectors可能来自此。

转到pandas的替代方法是使用非常富有表现力的R包dplyr。自版本2.7.0起,rpy2正在为其提供量身定制的界面:

from rpy2.robjects.lib import dplyr
dd = (dplyr.DataFrame(dd)
      .mutate(treat = 'ifelse(treat==1, 1, 0)')

在你的回答中已经指出公式应该 如此声明(公式是R中的语言对象,但有 没有Python语言级别的等效项。写这篇文章时 作为一个常见的Python调用:

fit1 = uplift.upliftRF(formula = robjects.Formula('y ~ X1 + X2 + X3 + X4 + X5 + X6 + trt(treat)'),
                       mtry = 3,
                       ntree = 200,
                       split_method = 'KL',
                       minsplit = 200,
                       data = dd)