Що означає "методи S3" в R?


124

Оскільки я досить новачок у R, я не знаю, що таке методи та об’єкти S3. Я виявив, що існують об'єктні системи S3 і S4, і деякі рекомендують, якщо можливо, використовувати S3 над S4 (Дивіться Посібник зі стилів R Google за адресою http://google-styleguide.googlecode.com/svn/trunk/google-r-style. html ) *. Однак я не знаю точного визначення методів / об'єктів S3.

Оновлення: Станом на 2019 рік, тут є гіперпосилання Google Guide щодо стилю Google .

Відповіді:


85

Більшість відповідної інформації можна знайти, переглянувши ?S3або ?UseMethod, коротко кажучи:

S3 відноситься до схеми методу диспетчеризації. Якщо ви використовували R на деякий час, ви помітите , що є print, predictі summaryметоди багато різних видів об'єктів.

У S3 це працює за:

  • встановлення класу об'єктів, що цікавлять (наприклад: повернення значення виклику методу glmмає клас glm)
  • надаючи метод із загальною назвою (наприклад print), то точка, а потім ім'я класу (наприклад: print.glm)
  • певна підготовка повинна бути виконана до цього загального імені ( print), щоб це спрацювало, але якщо ви просто хочете відповідати себе існуючим іменам методів, вам це не потрібно (див. допомогу, до якої я звертався раніше, якщо це зробити ).

В очах дивиться, і , в зокрема, користувач новоствореного пакету фанки модель фитинга, це набагато зручніше , щоб мати можливість ввести predict(myfit, type="class")ніж predict.mykindoffit(myfit, type="class").

Це є ще трохи, але це має розпочати. У цього способу диспетчеризації, заснованого на атрибуті (класі) об'єктів, існує досить багато недоліків (а пуристики, ймовірно, лягають уночі в жах від цього), але для багатьох ситуацій він працює гідно. З поточною версією R впроваджено новіші способи (S4 та еталонні класи), але більшість людей все ще (тільки) використовують S3.


54

Щоб розпочати роботу з 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's in the stats package
stats:::print.acf

39

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

Три системи O R відрізняються тим, як визначаються класи та методи:

  • S3 реалізує стиль програмування OO під назвою OO generic-function. Це відрізняється від більшості мов програмування, таких як Java, C ++ і C #, які реалізують OO, що передає повідомлення. При передачі повідомлень повідомлення (методи) надсилаються об'єктам і об'єкт визначає, яку функцію викликати. Зазвичай цей об'єкт має особливий вигляд у виклику методу, який зазвичай з’являється перед назвою методу / повідомлення: наприклад, canvas.drawRect ("синій"). S3 відрізняється. Хоча обчислення все ще здійснюються за допомогою методів, спеціальний тип функції, яка називається загальною функцією, вирішує, який метод викликати, наприклад, drawRect (полотно, "синій"). S3 - дуже випадкова система. У ньому немає формального визначення класів.

  • S4 працює аналогічно S3, але є більш формальним. Є дві основні відмінності щодо S3. S4 має формальні визначення класів, які описують представлення та успадкування для кожного класу, і має спеціальні допоміжні функції для визначення родових та методів. S4 також має багаторазове відправлення, що означає, що загальні функції можуть вибирати методи на основі класу будь-якої кількості аргументів, а не лише одного.

  • Довідкові класи, які називаються RC коротко, сильно відрізняються від S3 та S4. RC реалізує OO, що передає повідомлення, тому методи належать до класів, а не до функцій. $ використовується для розділення об'єктів і методів, тому виклики методів мають вигляд полотна $ drawRect ("синій"). RC-об’єкти також змінюються: вони не використовують звичайну семантику копіювання-модифікації, але змінюються на місці. Це ускладнює їх міркування, але дозволяє вирішувати проблеми, які важко вирішити за допомогою S3 або S4.

Також є ще одна система, яка не є достатньо OO, але тут важливо згадати:

  • базові типи, внутрішні типи рівня С, що лежать в основі інших систем ОО. Базовими типами в основному маніпулюють за допомогою коду С, але про них важливо знати, оскільки вони забезпечують будівельні блоки для інших систем ОО.

11

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


10

Спробуйте

methods(residuals)

який перераховує, серед іншого, "остаточні.lm" та "остаточні.glm". Це означає, що ви встановили лінійну модель, m та типresiduals(m), залишиться.lm буде викликано. Коли ви вмонтуєте узагальнену лінійну модель, буде виклик залишків.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). Якщо ви шукаєте щось подібне до останнього, ознайомтеся з пакетом прото.


Я майже впевнений, що ідея функцій-членів та методів, що належать до об'єктів, не має великого сенсу в Р. Методи не належать до об'єктів (також функції є і об'єктами), але належать до функції.
petermeissner

3

Ось оновлений швидко зношеному з численних систем R об'єкта в відповідно до «Advanced R, 2 - е видання» (CRC Press, 2019) по Hadley Уікхемом (головний науковий співробітник RStudio), який має веб - представництво тут , на основі глави про об'єкті -Орієнтоване програмування .

Обкладинка книги Advanced R

Перше видання з 2015 року , має веб - представництво тут , з відповідною главою про OO тут .

Підходи до систем ОО

Хедлі визначає наступне, щоб виділити два різних підходи до програмування ОО:

Функціональний OOP : методи (фрагменти коду, що дзвоняться) належать до загальних функцій (не плутати з загальними методами Java / C # ). Подумайте, як методи розташовані у глобальній таблиці пошуку. Метод виконання виконується системою виконання на основі назви функції та типу (або класу об'єктів) одного або декількох аргументів, переданих цій функції (це називається "метод відправки"). Синтаксис-навхрест, виклики методів можуть виглядати як звичайні виклики функцій: myfunc(object, arg1, arg2). Цей виклик призведе до того, що час виконання буде шукати метод, пов’язаний з парою ("myfunc", typeof (об'єкт)) або можливо ("myfunc", typeof (об'єкт), typeof (arg1), typeof (arg2))якщо мова це підтримує. У R3 S3 повне ім’я родової функції дає пару (функція-ім’я, клас) . Наприклад: mean.Dateце метод обчислення середнього значення Дат. Спробуйте methods("mean")перелічити загальні методи з назвою функції mean. Функціональний підхід OOP знайдений, наприклад, у піонері OO Smalltalk , загальній системі об'єктів Lisp та Julia . Хедлі зазначає, що "У порівнянні з R, реалізація Джулії є повністю розвиненою та надзвичайно ефективною".

Інкапсульований OOP : методи належать до об'єктів або класів, а виклики методів зазвичай виглядають так object.method(arg1, arg2). Це називається капсульованим, оскільки об’єкт інкапсулює як дані (поля), так і поведінку (методи). Подумайте про метод, який знаходиться в таблиці пошуку, доданій до об'єкта або в описі класу об'єкта. Час виконання виглядає методом на основі назви методу та, можливо, типу одного або декількох аргументів. Такий підхід знайдений у «популярних» мовах OO, таких як C ++, Java, C #.

В обох випадках, якщо підтримання успадкування (це, мабуть, є), час виконання може пройти ієрархію класів вгору, поки не знайде збіг для ключа пошуку викликів.

Як дізнатися, до якої системи належить R-об’єкт

library(sloop) # formerly, "pryr"
otype(mtcars)
#> [1] "S3"

Об'єктні системи R

S3

  • Функціональний підхід OOP.
  • Найважливіша система за Едлі.
  • Найпростіший, найпоширеніший. Перша система ОО використовувала Р.
  • Поставляється з основою R, використовується на всій основі R.
  • Покладається на конвенції, а не на примусові гарантії.
  • Дивіться Чемберс, Джон М і Тревор Дж. Хасті. 1992. "Статистичні моделі в С." Wadsworth & Brooks / Cole Advanced Books & Software.
  • Деталі у "Advanced R, 2-е видання" тут .

S4

  • Функціональний підхід OOP.
  • Третя найважливіша система за Едлі.
  • Перепишіть S3, тому схожий на S3, але більш формальний і суворіший: він змушує вас ретельно продумати дизайн програми. Підходить для побудови великих систем (наприклад, проект Біокондуктор ).
  • Реалізовано в базовому пакеті «методи».
  • Див .: Chambers, John M. 1998. "Програмування з даними: Посібник з мови S". Спрингер.
  • Деталі у "Advanced R, 2-е видання" тут .

RC aka "Довідкові класи"

  • Інкапсульований підхід ООП.
  • Поставляється з базовою Р.
  • На основі S4.
  • RC-об'єкти - це особливий тип об'єктів S4, які також є "мутаційними". тобто замість використання звичайної семантики копіювання-модифікації R вони можуть бути змінені на місці. Зауважте, що стан, що змінюється, важко пояснити та стати джерелом некрасивих помилок, але може призвести до більш ефективного коду в певних програмах.

R6

  • Інкапсульований підхід ООП.
  • Друга найважливіша система за Едлі.
  • Можна знайти в пакеті R6 (встановити за допомогою library(R6))
  • Схожий на RC, але легший і набагато швидший: він не залежить від S4 або пакету методів . Побудований на вершині R середовища. Також має:
    • публічні та приватні методи
    • активні прив'язки (поля, які при зверненні насправді викликають метод)
    • успадкування класу, який працює в пакетах
    • обидва метод класу (код , який належить до класу і може отримати доступ до примірника з допомогою self, private, super) і функціями членів (функції , призначені на поля, але які не є методами, тільки функція)
  • Забезпечує стандартизований спосіб уникнути семантики "копіювання на зміну" R
  • Дивіться на сайті пакета: "R6: Інкапсульоване об'єктно-орієнтоване програмування для R" .
  • Деталі у "Advanced R, 2-е видання" тут .

Інші

Є й інші, наприклад R.oo (схожий на RC), proto (на основі прототипу, думаю, JavaScript) та Mutatr . Однак "Advanced R" говорить:

Крім R6, який широко використовується, ці системи представляють насамперед теоретичний інтерес. Вони мають свої сильні сторони, але мало хто з користувачів R знає і розуміє їх, тому іншим важко читати та сприяти вашому коду.

Не забудьте також прочитати розділ про компроміси у "Advanced R, 2-е видання" .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.