Поскольку я довольно новичок в R, я не знаю, что такое методы и объекты S3. Я обнаружил, что существуют объектные системы S3 и S4, а некоторые рекомендуют использовать S3 по S4, если это возможно (http://google-styleguide.googlecode.com/svn/trunk/google-r-style.html). Однако я не знаю точное определение методов/объектов S3.
Что означает "методы S3" в R?
Ответ 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)
. Если вы ищете что-то вроде последнего, посмотрите на прото-пакет.