Что означает "методы S3" в R?
Поскольку я довольно новичок в R, я не знаю, что такое методы и объекты S3. Я обнаружил, что существуют объектные системы S3 и S4, а некоторые рекомендуют использовать S3 по S4, если это возможно (http://google-styleguide.googlecode.com/svn/trunk/google-r-style.html). Однако я не знаю точное определение методов/объектов S3.
Ответы
Ответ 1
Большинство релевантной информации можно найти, посмотрев ?S3
или ?UseMethod
, но в двух словах:
S3 относится к схеме диспетчеризации метода. Если вы некоторое время используете R, вы заметите, что существуют методы print
, predict
и summary
для множества разных объектов.
В S3 это работает:
- задание класса объектов
интерес (например: возвращаемое значение
вызов метода
glm
имеет класс glm
)
- обеспечивающий метод с общим
имя (например,
print
), затем точка и
затем имя класса (например:
print.glm
)
- какая-то подготовка должна была быть
сделанное с этим общим именем (
print
)
для этого, но если вы
просто желая соответствовать
существующие имена методов, вам не нужно
это (см. справку, на которую я ссылался
раньше, если вы это сделаете).
В глазах смотрящего, и особенно пользователя вашего недавно созданного фанк-модельного пакета, гораздо удобнее вводить predict(myfit, type="class")
, чем predict.mykindoffit(myfit, type="class")
.
Для этого есть немного больше, но это должно заставить вас начать. Есть немало недостатков в этом способе отправки методов, основанных на атрибуте (классе) объектов (и пуристы C, вероятно, небудут ночью в ужасе от него), но для многих ситуаций он работает прилично. С текущей версией R были реализованы новые способы (S4 и ссылочные классы), но большинство людей все еще (только) используют S3.
Ответ 2
Чтобы начать работу с S3, посмотрите код для функции median
. Ввод median
в командной строке показывает, что в его теле есть одна строка, а именно
UseMethod("median")
Это означает, что это метод S3. Другими словами, у вас может быть другая функция median
для разных классов S3. Чтобы перечислить все возможные медианные методы, введите
methods(median) #actually not that interesting.
В этом случае существует только один метод, по умолчанию, который вызывается для чего-либо. Вы можете увидеть код для этого, набрав
median.default
Более интересным примером является функция print
, которая имеет много разных методов.
methods(print) #very exciting
Обратите внимание, что некоторые из методов имеют *
рядом с их именем. Это означает, что они скрыты внутри некоторого пространства имен пакетов. Используйте find
, чтобы узнать, в каком пакете они находятся. Например
find("acf") #it in the stats package
stats:::print.acf
Ответ 3
Из http://adv-r.had.co.nz/OO-essentials.html:
Rs три системы OO различаются тем, как определяются классы и методы:
-
S3 реализует стиль программирования OO, называемый универсальной функцией OO. Это отличается от большинства языков программирования, таких как Java, С++ и С#, которые осуществляют передачу OO сообщений. При передаче сообщений сообщения (методы) отправляются объектам, и объект определяет, какая функция звонить. Как правило, этот объект имеет особый вид в методе вызов, обычно появляющийся перед именем метода/сообщения: например. canvas.drawRect( "синий" ). S3 отличается. Пока вычисления все еще осуществляемый с помощью методов, специальный тип функции, называемый общим функция решает, какой метод вызывать, например, drawRect (холст, "синий" ). S3 - очень случайная система. Он не имеет формального определения классов.
-
S4 работает аналогично S3, но является более формальным. Есть два основных отличия от S3. S4 имеет формальные определения классов, которые описывают представление и наследование для каждого класса и имеет специальный помощник функции для определения дженериков и методов. S4 также имеет несколько отправка, что означает, что общие функции могут выбирать методы, основанные на класс любого числа аргументов, а не только один.
-
Ссылочные классы, называемые RC для краткости, сильно отличаются от S3 и S4. RC реализует передачу сообщений OO, поэтому методы принадлежат классы, а не функции. $используется для разделения объектов и методов, поэтому вызов метода выглядит как холст $drawRect ( "синий" ). Объекты RC также mutable: они не используют обычную семантику Rs для копирования-на-модификации, но являются модифицировано на месте. Это затрудняет их рассуждение, но позволяет чтобы решить проблемы, которые трудно решить с помощью S3 или S4.
Также существует еще одна система, которая не совсем OO, но ее важная здесь:
- базовые типы, внутренние типы C-уровня, которые лежат в основе других OO системы. Базовые типы в основном обрабатываются с использованием кода C, но theyre важно знать, потому что они обеспечивают строительные блоки для другие системы OO.
Ответ 4
Я пришел к этому вопросу, в основном задаваясь вопросом, откуда пришли имена. Из этой статьи в википедии видно, что имя относится к версии языка программирования S, на которой основана R. Схемы диспетчеризации метода, описанные в других ответах, поступают из S и соответствующим образом помечены в соответствии с версией.
Ответ 5
Try
methods(residuals)
который перечисляет, среди прочего, "остатки .lm" и "residuals.glm". Это означает, что, когда вы установили линейную модель, m и тип residuals(m)
, вызывается остаток. Lm. Когда вы установите обобщенную линейную модель, будет вызываться остаток .glm.
Это вроде объектная модель С++ перевернулась. В С++ вы определяете базовый класс, имеющий виртуальные функции, которые переопределяются производным классом.
В R вы определяете виртуальную (aka generic) функцию, а затем вы решаете, какие классы переопределяют эту функцию (также известный как метод). Обратите внимание, что классы, выполняющие это, не должны выводиться из одного общего суперкласса.
Я бы не согласился, как правило, предпочитать S3 над S4. S4 имеет больше формализма (= больше ввода), и это может быть слишком много для некоторых приложений. Однако классы S4 могут быть определены как класс или структура в С++. Вы можете указать, что объект определенного класса состоит из строки и двух чисел, например:
setClass("myClass", representation(label = "character", x = "numeric", y = "numeric"))
Методы, вызываемые с объектом этого класса, могут опираться на объект, имеющий эти члены. Это очень отличается от классов S3, которые представляют собой список пучков элементов.
С S3 и S4 вы вызываете функцию-член на fun(object, args)
, а не на object$fun(args)
. Если вы ищете что-то вроде последнего, посмотрите на прото-пакет.