【问题标题】:How to execute S4 class method in Python (using rpy2)?如何在 Python 中执行 S4 类方法(使用 rpy2)?
【发布时间】:2020-07-24 08:20:18
【问题描述】:

我在 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')
       }
    }
  )
)

现在,我可以创建此类的一个实例并在其上执行“test_method”:

object <- test_class(A='hello')
object$test_method('hi')

这会返回“否”,因为字符串不相等。

现在我想保存我制作的这个对象并从 Python 执行“test_method”。我制作了一个 RDS:

saveRDS(object, 'object.rds')

现在我知道如何使用 rpy2 将这个对象读入 Python(但是我并不关心使用哪个包,因为它可以工作):

from rpy2.robjects import R
r = R()
r_object = r.readRDS("object.rds")

但是我现在如何执行“test_method”?我试过了,但它不起作用:

r_object.test_method('hi')

这会抛出:“AttributeError: 'RS4' object has no attribute 'test_method'”

【问题讨论】:

    标签: python r rpy2 s4


    【解决方案1】:

    rpy2 documentation about S4 classes 没有很好地涵盖引用类,主要是因为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
    

    编写从该泛型类继承的子类可以如下所示:

    class TestClass(ro.methods.RS4): 
        def test_method(self, b): 
            return ro.baseenv['$'](self, 'test_method')(b) 
    

    强制转换简单且计算成本低(父类的构造函数只会传递一个已经是 S4 对象的 R 对象):

    s4testobj = TestClass(s4obj)
    

    现在我们可以这样做了:

    >>> tuple(s4testobj.test_method('hi'))  
     ('no',)                                         
    

    要在 Python 中从 R 类定义自动创建方法和属性,以及转换为自定义子级,您需要在 Python 端使用元编程,并定义自定义转换(有指向后者的链接在前面提供的文档的链接中)。

    注意:如果不绑定到 S4 参考类,R6 类系统值得一看。该类系统的rpy2 映射在这里:https://github.com/rpy2/rpy2-R6

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-22
      • 1970-01-01
      • 1970-01-01
      • 2018-04-10
      • 2019-09-14
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多