В R, как можно создать метод объекта S4, который напрямую корректирует значения внутри слотов этого объекта? - PullRequest
4 голосов
/ 05 августа 2010

Есть ли способ, позволяющий методу объекта S4 напрямую корректировать значения внутри слотов этого объекта, не копируя весь объект в память и не перезаписывая его в родительскую среду в конце метода ? Прямо сейчас у меня есть объект, который имеет слоты, в которых он отслеживает свое собственное состояние. Я вызываю метод, который переводит его в следующее состояние, но сейчас мне кажется, что мне нужно присвоить () каждое значение (или копию объекта, вызывающего метод) обратно в родительскую среду. В результате объектно-ориентированный код, кажется, работает намного медленнее, чем код, который просто корректирует различные переменные состояния в цикле.

Ответы [ 3 ]

4 голосов
/ 29 августа 2014

R имеет три объектно-ориентированные (ОО) системы: S3 , S4 и эталонные классы (где последние некоторое время назывались [[R5]], но их официальное название - «Справочные классы»).

Эталонные классы (или рефклассы) являются новыми в 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 / method / ReferenceClasses

3 голосов
/ 30 августа 2010

Я сам задал этот вопрос в R-списке и нашел обходной путь для имитации передачи по ссылке, что-то в стиле:

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

Вдали от самого чистого кода вокруг, я бы сказал ...

Предложение, поступающее из списка R-help, использует среду для рассмотрения этих случаев. РЕДАКТИРОВАТЬ: введен измененный код.

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) {
    object@.cache$masterlist[[name]] <- value
  })

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

setMethod("rv",signature=c("MyClass","character"),
  function(object, name) {
    return(object@.cache$masterlist[[name]])
  })
1 голос
/ 05 августа 2010

Насколько я знаю (и если я вас правильно понял), вы должны заново скопировать весь объект.Вы не можете легко передавать значения по ссылке, они всегда передаются «по значению».Поэтому, как только вы изменили (копию) вашего объекта, вам необходимо скопировать его обратно в ваш объект.

Джон Чембер довольно ясно говорит об этом в своей книге Программное обеспечение для анализа данных .Это способ избежать неожиданностей или побочных эффектов.

Я думаю, что есть некоторые обходные пути, использующие среды, но я не могу помочь с этим.

...