Как использовать S4 объектное программирование в R
Что не так с моим сценарием R? Я пытаюсь использовать вектор пользовательских объектов (здесь вектор объектов "Страница") в другом пользовательском объекте (здесь объект "Книга")
setClass("Page",
slots = c(PageNo = "numeric", #scalar
Contents = "character") #vector of strings
)
setClass("Book",
slots = c(Pages = "vector", # Something wrong here? vector of pages ? "Page" or vector" or "list"
Title = "character") #vector of strings
)
setGeneric(name="AddPage", def=function(aBook, pageNo){standardGeneric("AddPage")})
setMethod(f="AddPage", signature="Book",
definition=function(aBook, pageNo)
{
page1 = new("Page")
page1@PageNo = pageNo
aBook@Pages = c(aBook@Pages, page1) # Something wrong here?
}
)
book1 = new("Book")
book1@Title = "Sample Book"
book1
book1@Pages
AddPage(book1, 1)
AddPage(book1, 2)
book1@Pages
1 ответ
Помните, что R не использует ссылочную семантику, поэтому AddPage(book1, 1)
создает копию book1 и обновляет ее. В методе вы не возвращаете обновленный объект, а book1 остается неизменным.
Обновите метод, чтобы он возвращал измененный объект
setMethod(f="AddPage", signature="Book",
definition=function(aBook, pageNo)
{
page1 = new("Page")
page1@PageNo = pageNo
aBook@Pages = c(aBook@Pages, page1) # Something wrong here?
aBook
}
)
и присвоить возвращаемое значение старой переменной
book1 = AddPage(book1, 1)
Но это очень неэффективный подход - линия aBook@Pages = c(aBook@Pages, page1)
делает копию всех существующих страниц (справа, чтобы создать более длинный вектор; он масштабируется с квадратом числа страниц, добавленных в книгу), а затем копирует всю книгу (для назначения). Кроме того, создание отдельных объектов стоит дорого и не использует "векторизацию" R. Первым шагом является представление об объекте "Страница" вместо "Страницы", где объект моделирует столбцы, а не строки фрейма данных. В этом случае "Book" не имеет вектора объектов Page, а имеет один объект Pages. Это также подразумевает другой подход к созданию вашей "книги".