Что означает "методы 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). Если вы ищете что-то вроде последнего, посмотрите на прото-пакет.