在 R 中,如何为 S4 对象创建一种方法来直接调整该对象槽内的值?

发布于 2024-09-13 03:39:36 字数 187 浏览 1 评论 0原文

有没有办法允许 S4 对象的方法直接调整该对象插槽内的值,而无需将整个对象复制到内存中,并且必须在方法结束时将其重新写入父环境?现在我有一个对象,它有一些槽来跟踪自己的状态。我调用了一个将其推进到下一个状态的方法,但现在看来我必须将每个值(或调用该方法的对象的副本)分配回父环境。因此,面向对象的代码的运行速度似乎比简单地调整循环中的各种状态变量的代码慢很多。

Is there a way to allow a method of an S4 object to directly adjust the values inside the slots of that object without copying the entire object into memory and having to re-write it to the parent environment at the end of the method? Right now I have an object that has slots where it keeps track of its own state. I call a method that advances it to the next state, but right now it seems like I have to assign() each value (or a copy of the object invoking the method) back to the parent environment. As a result, the object oriented code seems to be running a lot slower than code that simply adjusts the various state variables in a loop.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

意犹 2024-09-20 03:39:36

R 具有三个面向对象 (OO) 系统:S3S4参考类(后者一度被称为 [[ R5]],但它们的正式名称是参考类)。

参考类(或 refclasses)是 R 2.12 中的新增内容。它们满足了对可变对象的长期需求,而这些需求以前是由 R.oo、proto 和 mutatr 等非核心包来满足的。虽然核心功能很可靠,但参考类仍在积极开发中,一些细节将会发生变化。参考类的最新文档始终可以在 ?ReferenceClasses 中找到。

引用类与 S3 和 S4 之间有两个主要区别:

  • Refclass 对象使用消息传递 OO
  • Refclass 对象是可变的:修改语义上的常见 R 副本会这样做
    不适用。

这些属性使得该对象系统的行为更像 Java 和 C#。
在这里阅读更多信息:

  1. http://adv-r.had.co.nz/ R5.html

  2. http://www .inside-r.org/r-doc/methods/ReferenceClasses

R has three object oriented (OO) systems: S3, S4 and Reference Classes (where the latter were for a while referred to as [[R5]], yet their official name is Reference Classes).

Reference Classes (or refclasses) are new in R 2.12. They fill a long standing need for mutable objects that had previously been filled by non-core packages like R.oo, proto and mutatr. While the core functionality is solid, reference classes are still under active development and some details will change. The most up-to-date documentation for Reference Classes can always be found in ?ReferenceClasses.

There are two main differences between reference classes and S3 and S4:

  • Refclass objects use message-passing OO
  • Refclass objects are mutable: the usual R copy on modify semantics do
    not apply.

These properties makes this object system behave much more like Java and C#.
read more here:

  1. http://adv-r.had.co.nz/R5.html

  2. http://www.inside-r.org/r-doc/methods/ReferenceClasses

半步萧音过轻尘 2024-09-20 03:39:36

我自己在 R 列表上问了这个问题,并找到了一种解决方法来模拟通过引用传递,其风格如下:

eval(
  eval(
     substitute(
        expression(object@slot <<- value)
     ,env=parent.frame(1) )
  )
)

远离我想说的最干净的代码......

来自 R 的建议帮助列表,使用一个环境来处理这些情况。
编辑:插入调整后的代码。

setClass("MyClass", representation(.cache='environment',masterlist="list"))

setMethod("initialize", "MyClass",
  function(.Object, .cache=new.env()) {
    .Object@masterlist <- list()
    callNextMethod(.Object, .cache=.cache)
  })

sv <- function(object,name,value) {} #store value

setMethod("sv",signature=c("MyClass","character","vector"),
  function(object, name, value) {
    [email protected]$masterlist[[name]] <- value
  })

rv <- function(object,name) {} #retrieve value

setMethod("rv",signature=c("MyClass","character"),
  function(object, name) {
    return([email protected]$masterlist[[name]])
  })

I asked this question on the R-list myself, and found a work-around to simulate a pass by reference, something in the style of :

eval(
  eval(
     substitute(
        expression(object@slot <<- value)
     ,env=parent.frame(1) )
  )
)

Far from the cleanest code around I'd say...

A suggestion coming from the R-help list, uses an environment to deal with these cases.
EDIT : tweaked code inserted.

setClass("MyClass", representation(.cache='environment',masterlist="list"))

setMethod("initialize", "MyClass",
  function(.Object, .cache=new.env()) {
    .Object@masterlist <- list()
    callNextMethod(.Object, .cache=.cache)
  })

sv <- function(object,name,value) {} #store value

setMethod("sv",signature=c("MyClass","character","vector"),
  function(object, name, value) {
    [email protected]$masterlist[[name]] <- value
  })

rv <- function(object,name) {} #retrieve value

setMethod("rv",signature=c("MyClass","character"),
  function(object, name) {
    return([email protected]$masterlist[[name]])
  })
活泼老夫 2024-09-20 03:39:36

据我所知(如果我理解正确的话),你必须重新复制整个对象。您不能轻松地通过引用传递值,它总是“按值”传递。因此,一旦修改了对象(的副本),您需要将其重新复制回您的对象。

John Chamber 在他的书中对此非常明确 数据分析软件。这是避免意外或副作用的一种方法。

我认为使用环境有一些解决方法,但我无能为力。

As far as I know (and if I get you correctly), you have to recopy the whole object. You can't easily pass values by reference, it is always passed "by value". So once you have modified (a copy of) your object, you need to recopy it back to your object.

John Chamber is pretty explicit about it in his book Software for Data Analysis. It's a way to avoid surprises or side effects.

I think there are some workaround using environments, but I can't help with this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文