Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中执行S4类方法(使用rpy2)?_Python_R_Rpy2_S4 - Fatal编程技术网

如何在Python中执行S4类方法(使用rpy2)?

如何在Python中执行S4类方法(使用rpy2)?,python,r,rpy2,s4,Python,R,Rpy2,S4,我在R中创建了下面的S4类,它的构造函数接受一个名为“a”的变量,它是一个字符串。该类有一个名为“test_method”的方法,该方法将字符串“B”作为输入,并返回“a”是否等于“B” test_class <- setRefClass( "test_class", fields=list(A="character"), methods = list( test_method = function(B) { if

我在R中创建了下面的S4类,它的构造函数接受一个名为“a”的变量,它是一个字符串。该类有一个名为“test_method”的方法,该方法将字符串“B”作为输入,并返回“a”是否等于“B”

test_class <- setRefClass(
  "test_class",
  fields=list(A="character"),
  methods = list(
    test_method = function(B) {
       if (A==B) {
           return('yes')
       } else {
           return('no')
       }
    }
  )
)
现在我知道了如何使用rpy2将这个对象读入Python(但是我并不真正关心使用哪个包,因为它可以工作):

但我现在如何执行“test_方法”?我试过这个,但不起作用:

r_object.test_method('hi')
这抛出:“AttributeError:'RS4'对象没有属性'test_method'”

没有很好地覆盖引用类,主要是因为
rpy2
代码早于S4的引用类扩展

简而言之,S4引用类没有映射到Python属性,但是编写一个子Python类这样做相对容易

import rpy2.robjects as ro
test_class = ro.r("""
  setRefClass(
    "test_class",
    fields=list(A="character"),
    methods = list(
      test_method = function(B) {
         if (A==B) {
             return('yes')
         } else {
             return('no')
         }
      }
    )
  )
""")
s4obj = test_class(A='hello')
我们有一个相当通用的S4对象:

>>> type(s4obj)
rpy2.robjects.methods.RS4
s4testobj = TestClass(s4obj)
编写从该泛型类继承的子类可以如下所示:

class TestClass(ro.methods.RS4): 
    def test_method(self, b): 
        return ro.baseenv['$'](self, 'test_method')(b) 
强制转换简单且计算成本低(父类的构造函数将只通过已经是S4对象的R对象):

现在我们可以做:

>>> tuple(s4testobj.test_method('hi'))  
 ('no',)                                         
要在Python中从R类定义自动创建更多的方法和属性,并转换到自定义子级,您需要在Python端使用元编程,并定义自定义转换(在前面提供的文档链接中有到后者的链接)

注:如果没有绑定到S4参考类,R的R6类系统值得一看。该类系统的
rpy2
映射如下:。

主要因为
rpy2
代码早于S4的参考类扩展,所以没有很好地涵盖参考类

简而言之,S4引用类没有映射到Python属性,但是编写一个子Python类这样做相对容易

import rpy2.robjects as ro
test_class = ro.r("""
  setRefClass(
    "test_class",
    fields=list(A="character"),
    methods = list(
      test_method = function(B) {
         if (A==B) {
             return('yes')
         } else {
             return('no')
         }
      }
    )
  )
""")
s4obj = test_class(A='hello')
我们有一个相当通用的S4对象:

>>> type(s4obj)
rpy2.robjects.methods.RS4
s4testobj = TestClass(s4obj)
编写从该泛型类继承的子类可以如下所示:

class TestClass(ro.methods.RS4): 
    def test_method(self, b): 
        return ro.baseenv['$'](self, 'test_method')(b) 
强制转换简单且计算成本低(父类的构造函数将只通过已经是S4对象的R对象):

现在我们可以做:

>>> tuple(s4testobj.test_method('hi'))  
 ('no',)                                         
要在Python中从R类定义自动创建更多的方法和属性,并转换到自定义子级,您需要在Python端使用元编程,并定义自定义转换(在前面提供的文档链接中有到后者的链接)

注:如果没有绑定到S4参考类,R的R6类系统值得一看。该类系统的
rpy2
映射如下: