Автоматическое назначение в методах initialize () для Ссылочных Классов в R - PullRequest
8 голосов
/ 13 апреля 2011

Я работаю со справочным классом с несколькими десятками полей.Я настроил метод initialize(), который принимает объект списка. Хотя некоторые поля зависят от дальнейших вычислений из элементов списка, большинство полей напрямую назначаются из элементов списка следующим образом:

fieldA <<- list$A
fieldB <<- list$B

Я думал, что было бы неплохо немного автоматизировать это.Чтобы привести пример в псевдокоде R (этот пример, очевидно, не будет работать):

for (field in c('A', 'B', 'C', 'D'))
   field <<- list[[field]]

Я попытался сделать несколько обходов вокруг <<-, например, выполнив что-то вроде:

for field in c('A', 'B', 'C', 'D'))
  do.call('<<-' c(field, list[[field]])) 

но не игра в кости.

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

1 Ответ

7 голосов
/ 14 апреля 2011

Используйте .self, чтобы указать экземпляр, и выберите поля, используя [[. Я не уверен на 100% (но кто вообще?), Что [[ строго законно. Я добавил значения по умолчанию к lst, поэтому он работает, когда вызывается как C$new(), неявное предположение в S4, которое, похоже, похоже на кусочки аналогичным образом с эталонными классами.

C <- setRefClass("C",
    fields=list(a="numeric", b="numeric", c="character"),
    methods=list(
      initialize=function(..., lst=list(a=numeric(), b=numeric(), c=character()) 
        {
          directflds <- c("a", "b")
          for (elt in directflds)
              .self[[elt]] <- lst[[elt]]
          .self$c <- as.character(lst[["c"]])
          .self
      }))
c <- C$new(lst=list(a=1, b=2, c=3))

Или оставьте опцию для передачи списка или самих элементов пользователю с помощью

B <- setRefClass("B",
    fields=list(a="numeric", b="numeric", c="character"),
    methods=list(
      initialize=function(..., c=character()) {
          callSuper(...)
          .self$c <- as.character(c)
          .self
      }))
b0 <- B$new(a=1, b=2, c=3)
b1 <- do.call(B$new, list(a=1, b=2, c=3))

Это также, кажется, более терпимо к пропуску некоторых значений из вызова new().

...