【问题标题】:R: modify any function applied to a S4 classR:修改应用于 S4 类的任何函数
【发布时间】:2017-02-01 09:42:03
【问题描述】:

我一直在开发一个 S4 类,它本质上是一个带有一点额外信息的 data.frame。对于这个问题,这个类的“额外”特征是无关紧要的。重要的是该类包含一个存储在其中一个插槽中的 data.frame 对象。 (我将 data.frame 放在一个插槽中,而不是将其命名为超类,因为我发现包含 data.frames 的 S4 类出于某种原因将 data.frames 简化为列表)。

这是一个基本的例子:

setClass('tmp_class', slots = c(df = 'data.frame'))

test_object <- new('tmp_class', df = data.frame(Num = 1:10, Let = letters[1:10]))

现在我想做的是让应用于此类对象的 any 函数基本上应用于插槽@df 中的data.frame。为特定功能编写方法很容易,例如:

setMethod('dim', signature = c(x = 'tmp_class'), function(x) dim(x@df))

但我仅限于我能想到的功能,任何用户发明的功能都行不通。

编写一种包装器/闭包来修改函数以在我的类上工作是一件简单的事情,如下所示:

tmp_classize <- function(func){
   function(tmp, ...){ func(tmp@df, ...) }
}

所以,与其为 colnames() 或 ncol() 编写方法,我可以直接运行:

tmp_classize(colnames)(test_object)

tmp_classize(ncol)(test_object)

但我想做的是以某种方式自动调用应用于我的班级的any 函数上的“tmp_classize”函数。我不知道该怎么做。我在想,如果可以以某种方式调用具有类“tmp_class”的输入签名的“通用方法”,然后使用 sys.function() 来获取被调用的实际函数,也许我可以做一些工作,但是 A) 那里是递归问题 B)我不知道如何调用这种“通用”方法。在我看来,该解决方案(如果存在的话)可能需要非标准评估,我宁愿避免这种情况,但如有必要可能会使用。

谢谢!

附:我意识到这项工作可能是不明智/糟糕的编程技术,我可能永远不会真正在一个包中实现它。我仍然很想知道这是否可能。

附言我也对应用于 S3 类的相同想法感兴趣!

【问题讨论】:

    标签: r methods closures s4


    【解决方案1】:

    原则上你可以做的是为你的班级和data.frame创建一个classUnion,并为你的班级编写处理所有读写data.frames的方法,例如$,@ 987654325@、dim()&lt;- 等等。然后,当其他函数试图将您的新类用作data.frame 时,会有一些方法可以使其工作。从第 375 页开始的 John Chambers “数据分析软件”中对此进行了一些解释。也就是说,该系统可能很难实施。

    一个更简单的系统可能是向您的data.frame 添加一个额外的属性以及您需要的额外信息。例如:

    x<-data.frame(a=1:3,b=4:6)
    attr(x,"Info")<-"Extra info I need"
    attributes(x)$Info
    [1] "Extra info I need"
    

    这不像S4 类那么优雅,但可以完成data.frame 所做的一切。我怀疑熟悉S3 类的人可以在这个想法上有所改进。

    【讨论】:

      【解决方案2】:

      最简单的解决方案是让您的类包含 data.frame,而不是将其作为插槽之一。例如这里是一个带有时间戳的data.frame

      setclass(
        "timestampedDF",
        slots=c(timestamp="POSIXt"),
        contains="data.frame"
      )
      

      现在所有适用于data.frame(例如head)的函数将自动适用于timestampedDF 对象。如果您需要获取“数据框部分”,则将其保存在隐藏插槽object@.Data

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多