Что означает «методы S3» в R? - PullRequest
107 голосов
/ 05 июля 2011

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

Ответы [ 5 ]

76 голосов
/ 05 июля 2011

Большую часть соответствующей информации можно найти, посмотрев на ?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.

47 голосов
/ 05 июля 2011

Чтобы начать работу с S3, посмотрите код для функции median.Ввод median в командной строке показывает, что в его теле находится одна строка, а именно

UseMethod("median")

Это означает, что это метод S3.Другими словами, вы можете иметь разные функции median для разных классов S3.Чтобы перечислить все возможные медианные методы, введите

methods(median) #actually not that interesting.  

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

median.default

Гораздо более интересным примером является функция print, которая имеет много различных методов.

methods(print)  #very exciting

Обратите внимание, что некоторые изметоды имеют * s рядом с их именем.Это означает, что они скрыты внутри пространства имен какого-либо пакета.Используйте find, чтобы узнать, в каком пакете они находятся. Например,

find("acf")  #it's in the stats package
stats:::print.acf
33 голосов
/ 20 мая 2014

С http://adv -r.had.co.nz / OO-essentials.html :

Три ОО-системы R отличаются по тому, как определяются классы и методы:

  • S3 реализует стиль программирования ОО, называемый обобщенной функцией ОО. Это отличается от большинства языков программирования, таких как Java, C ++ и C #, в котором реализована передача сообщений OO. С передачей сообщений, сообщений (методы) отправляются объектам, и объект определяет, какая функция звонить. Как правило, этот объект имеет особый вид в методе вызов, обычно появляющийся перед названием метода / сообщения: например, canvas.drawRect ( "синий"). S3 отличается. Пока вычисления еще осуществляется через методы, особый тип функции, называемый универсальным Функция решает, какой метод вызвать, например, drawRect (canvas, "blue"). S3 очень случайная система. У него нет формального определения классов.

  • S4 работает аналогично S3, но является более формальным. Есть два основных отличия от S3. S4 имеет формальные определения классов, которые описывают представление и наследование для каждого класса, и имеет специальный помощник функции для определения дженериков и методов. S4 также имеет несколько диспетчеризация, что означает, что универсальные функции могут выбирать методы на основе класс любого количества аргументов, а не только одного.

  • Эталонные классы, для краткости называемые RC, весьма отличаются от S3. и S4. RC реализует ОО с передачей сообщений, поэтому методы принадлежат классы, а не функции. $ используется для разделения объектов и методов, поэтому вызовы методов выглядят как canvas $ drawRect ("blue"). RC объекты также изменяемые: они не используют обычную семантику R при копировании, но модифицировано на месте. Это делает их труднее рассуждать, но позволяет их, чтобы решить проблемы, которые трудно решить с S3 или S4.

Есть еще одна система, которая не совсем ОО, но это важно упомянуть здесь:

  • базовые типы, внутренние типы уровня C, которые лежат в основе других OO системы. Базовые типы в основном манипулируются с использованием кода на C, но важно знать, потому что они обеспечивают строительные блоки для другие ОО системы.
11 голосов
/ 02 ноября 2011

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

7 голосов
/ 06 июля 2011

Попробуйте

methods(residuals)

, в котором перечислены, среди прочего, "residuals.lm" и "residuals.glm". Это означает, что если вы укажете линейную модель m и тип residuals(m), будет вызван residuals.lm. Когда вы укажете обобщенную линейную модель, будет вызван residuals.glm. Это своего рода объектная модель C ++, перевернутая с ног на голову. В C ++ вы определяете базовый класс, имеющий виртуальные функции, которые переопределяются производным классом. В R вы определяете виртуальную (также называемую универсальной) функцию, а затем решаете, какие классы будут переопределять эту функцию (или определять метод). Обратите внимание, что классы, делающие это, не должны быть производными от одного общего суперкласса. Я бы не согласился вообще предпочесть S3, а не S4. S4 имеет больше формализма (= больше печатания), и это может быть слишком много для некоторых приложений. Классы S4, однако, могут быть определены как класс или структура в C ++. Вы можете указать, что объект определенного класса состоит из строки и двух чисел, например:

setClass("myClass", representation(label = "character", x = "numeric", y = "numeric"))

Методы, вызываемые с объектом этого класса, могут полагаться на объект, имеющий эти члены. Это сильно отличается от классов S3, которые представляют собой просто список элементов.

С S3 и S4 вы вызываете функцию-член fun(object, args), а не object$fun(args). Если вы ищете что-то вроде последнего, посмотрите на пакет proto.

...