Co oznacza „metody S3” w języku R?

124

Ponieważ jestem całkiem nowy w R, nie wiem, jakie są metody i obiekty S3. Odkryłem, że istnieją systemy obiektowe S3 i S4, a niektórzy zalecają używanie S3 zamiast S4, jeśli to możliwe (zobacz Przewodnik po stylu R firmy Google pod adresem http://google-styleguide.googlecode.com/svn/trunk/google-r-style. html ) *. Nie znam jednak dokładnej definicji metod / obiektów S3.

Aktualizacja: Począwszy od roku 2019, R Style Guide hiperłącza Google jest teraz tutaj .

jiggysoo
źródło

Odpowiedzi:

85

Większość istotnych informacji można znaleźć, przeglądając ?S3lub ?UseMethod, ale w skrócie:

S3 odnosi się do schematu wysyłki metod. Jeśli używany R na chwilę, można zauważyć, że istnieją print, predicti summarymetody wielu różnych rodzajów obiektów.

W S3 działa to przez:

  • ustawienie klasy obiektów zainteresowania (np .: zwracana wartość wywołania metody glmma klasę glm)
  • zapewnienie sposobu, za pomocą ogólnej nazwie (np print), a następnie kropka, a następnie nazwę klasy (np print.glm)
  • printAby to zadziałało, trzeba było zrobić pewne przygotowania z tą ogólną nazwą ( ), ale jeśli po prostu chcesz dostosować się do istniejących nazw metod, nie potrzebujesz tego (zobacz pomoc, do której odwoływałem się wcześniej, jeśli tak ).

Dla oka patrzącego, a zwłaszcza dla użytkownika nowo utworzonego pakietu dopasowania modeli funky, znacznie wygodniej jest pisać predict(myfit, type="class")niż predict.mykindoffit(myfit, type="class").

Jest w tym trochę więcej, ale to powinno zacząć. Ten sposób rozsyłania metod opartych na atrybucie (klasie) obiektów ma kilka wad (a puryści C prawdopodobnie nie śpią w przerażeniu), ale w wielu sytuacjach działa przyzwoicie. W obecnej wersji R zaimplementowano nowsze sposoby (S4 i klasy referencyjne), ale większość ludzi nadal (tylko) używa S3.

Nick Sabbe
źródło
54

Aby rozpocząć pracę z S3, spójrz na kod medianfunkcji. Wpisanie medianw wierszu polecenia ujawnia, że ​​ma on jedną linię w treści, a mianowicie

UseMethod("median")

Oznacza to, że jest to metoda S3. Innymi słowy, możesz mieć różne medianfunkcje dla różnych klas S3. Aby wyświetlić listę wszystkich możliwych metod mediany, wpisz

methods(median) #actually not that interesting.  

W tym przypadku jest tylko jedna metoda, domyślna, która jest wywoływana do wszystkiego. Możesz zobaczyć kod, wpisując

median.default

O wiele ciekawszym przykładem jest printfunkcja, która ma wiele różnych metod.

methods(print)  #very exciting

Zauważ, że niektóre metody mają *obok nazwy s. Oznacza to, że są one ukryte w przestrzeni nazw pakietu. Użyj, findaby dowiedzieć się, w którym pakiecie się znajdują. Na przykład

find("acf")  #it's in the stats package
stats:::print.acf
Richie Cotton
źródło
39

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

Trzy systemy obiektowe R różnią się sposobem definiowania klas i metod:

  • S3 implementuje styl programowania obiektowego zwany generycznym funkcjami obiektowymi. Różni się to od większości języków programowania, takich jak Java, C ++ i C #, które implementują OO z przekazywaniem komunikatów. W przypadku przekazywania komunikatów komunikaty (metody) są wysyłane do obiektów, a obiekt określa, którą funkcję wywołać. Zazwyczaj obiekt ten ma specjalny wygląd w wywołaniu metody, zwykle pojawia się przed nazwą metody / wiadomości: np. Canvas.drawRect ("niebieski"). S3 jest inny. Podczas gdy obliczenia są nadal wykonywane za pomocą metod, specjalny typ funkcji zwany funkcją ogólną decyduje, którą metodę wywołać, np. DrawRect (canvas, "blue"). S3 to bardzo swobodny system. Nie ma formalnej definicji klas.

  • S4 działa podobnie do S3, ale jest bardziej formalny. Istnieją dwie główne różnice w stosunku do S3. S4 ma formalne definicje klas, które opisują reprezentację i dziedziczenie dla każdej klasy, i ma specjalne funkcje pomocnicze do definiowania typów ogólnych i metod. S4 ma również wiele wysyłek, co oznacza, że ​​funkcje ogólne mogą wybierać metody na podstawie klasy dowolnej liczby argumentów, a nie tylko jednego.

  • Klasy referencyjne, w skrócie RC, różnią się znacznie od S3 i S4. RC implementuje OO z przekazywaniem komunikatów, więc metody należą do klas, a nie do funkcji. $ służy do oddzielania obiektów i metod, więc wywołania metod wyglądają jak canvas $ drawRect („niebieski”). Obiekty RC są również modyfikowalne: nie używają zwykłej semantyki R, ale są modyfikowane w miejscu. To utrudnia im rozumowanie, ale pozwala im rozwiązywać problemy, które są trudne do rozwiązania za pomocą S3 lub S4.

Jest jeszcze jeden system, który nie jest do końca OO, ale ważne jest, aby tu wspomnieć:

  • typy podstawowe, wewnętrzne typy poziomu C, które leżą u podstaw innych systemów obiektowych. Typy bazowe są przeważnie przetwarzane przy użyciu kodu C, ale warto o nich wiedzieć, ponieważ stanowią elementy konstrukcyjne dla innych systemów obiektowych.
Amit K. Thakur
źródło
11

Doszedłem do tego pytania głównie zastanawiając się, skąd wzięły się nazwy. Z tego artykułu w Wikipedii wynika, że ​​nazwa odnosi się do wersji języka programowania S, na której opiera się R. Schematy rozsyłania metod opisane w pozostałych odpowiedziach pochodzą z S i są odpowiednio oznaczone według wersji.

Jonathan Adelson
źródło
10

Próbować

methods(residuals)

który wymienia między innymi „residuals.lm” i „residuals.glm”. Oznacza to, że dopasowałeś model liniowy, m i typresiduals(m), zostanie wywołany plik residuals.lm. Po dopasowaniu uogólnionego modelu liniowego zostanie wywołany plik residuals.glm. To rodzaj modelu obiektowego C ++ wywróconego do góry nogami. W C ++ definiujesz klasę bazową mającą funkcje wirtualne, które są zastępowane przez klasy pochodne. W R definiujesz funkcję wirtualną (inaczej ogólną), a następnie decydujesz, które klasy zastąpią tę funkcję (inaczej zdefiniujesz metodę). Zauważ, że klasy, które to robią, nie muszą pochodzić z jednej wspólnej superklasy. Nie zgodziłbym się generalnie preferować S3 nad S4. S4 ma więcej formalizmu (= więcej pisania) i może to być za dużo dla niektórych zastosowań. Klasy S4 można jednak definiować jak klasę lub strukturę w C ++. Możesz określić, że obiekt określonej klasy składa się z ciągu znaków i dwóch liczb, na przykład:

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

Metody wywoływane z obiektem tej klasy mogą polegać na obiekcie mającym te elementy członkowskie. To bardzo różni się od klas S3, które są po prostu listą kilku elementów.

Z S3 i S4 wywołujesz funkcję składową przez, fun(object, args)a nie przez object$fun(args). Jeśli szukasz czegoś podobnego do tego ostatniego, spójrz na pakiet proto.

Harald Brendel
źródło
Jestem prawie pewien, że idea funkcji składowych i metod należących do obiektów nie ma tak dużego sensu w R. Metody nie należą do obiektów (również funkcje są obiektami), ale należą do funkcji.
petermeissner
3

Tutaj jest zaktualizowana szybko zniszczony z licznych systemów R obiektów według „Zaawansowane badania, wydanie 2” (CRC Press, 2019) przez Hadley Wickham (Chief Scientist w RStudio), który ma reprezentację internetowej tutaj , na podstawie rozdziału na temat obiektu -Zorientowane programowanie .

Okładka książki Advanced R.

Pierwsza edycja z 2015 r. Ma tutaj reprezentację internetową , a odpowiedni rozdział o OO tutaj .

Podejścia do systemów OO

Hadley definiuje następujące elementy, aby rozróżnić dwa różne podejścia do programowania obiektowego:

Funkcjonalne OOP : metody (wywoływalne fragmenty kodu) należą do funkcji ogólnych (nie należy ich mylić z metodami ogólnymi Java / C # ). Pomyśl o metodach jako znajdujących się w globalnej tabeli odnośników. Metoda do wykonania jest znajdowana przez system wykonawczy na podstawie nazwy funkcji i typu (lub klasy obiektu) co najmniej jednego argumentu przekazanego do tej funkcji (jest to nazywane „wysyłką metody”). Składnia mądry, wywołania metod może wyglądać zwykłych wywołań funkcji: myfunc(object, arg1, arg2). To wywołanie spowodowałoby, że środowisko wykonawcze szukało metody skojarzonej z parą („myfunc”, typeof (object)) lub prawdopodobnie („myfunc”, typeof (object), typeof (arg1), typeof (arg2))jeśli język to obsługuje. W S3 języka R pełna nazwa funkcji ogólnej daje parę (nazwa funkcji, klasa) . Na przykład: mean.Dateto metoda obliczania średniej z dat. Spróbuj methods("mean")wymienić ogólne metody z nazwą funkcji mean. Podejście funkcjonalne OOP można znaleźć na przykład w pionierze OO Smalltalk , Common Lisp Object System i Julii . Hadley zauważa, że „W porównaniu z R, implementacja Julii jest w pełni rozwinięta i niezwykle wydajna”.

Hermetyzowane OOP : metody należą do obiektów lub klas, a wywołania metod zwykle wyglądają jak object.method(arg1, arg2). Nazywa się to hermetyzacją, ponieważ obiekt hermetyzuje zarówno dane (pola), jak i zachowanie (metody). Wyobraź sobie, że metoda znajduje się w tabeli przeglądowej dołączonej do obiektu lub opisu klasy obiektu. Środowisko wykonawcze wyszukuje metodę na podstawie nazwy metody i prawdopodobnie typu co najmniej jednego argumentu. Jest to podejście stosowane w „popularnych” językach obiektowych, takich jak C ++, Java, C #.

W obu przypadkach, jeśli dziedziczenie jest obsługiwane (prawdopodobnie jest), środowisko wykonawcze może przechodzić przez hierarchię klas w górę, dopóki nie znajdzie dopasowania dla klucza wyszukiwania wywołania.

Jak dowiedzieć się, do jakiego systemu należy obiekt R.

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

Systemy obiektowe R.

S3

  • Funkcjonalne podejście OOP.
  • Najważniejszy system według Hadleya.
  • Najprostszy, najczęściej. Pierwszy system OO używany przez R.
  • W zestawie z podstawą R, używaną w całej bazie R.
  • Opiera się raczej na konwencjach niż na wymuszonych gwarancjach.
  • Zobacz Chambers, John M i Trevor J Hastie. 1992. „Modele statystyczne w S.” Wadsworth & Brooks / Cole Advanced Books & Software.
  • Szczegóły w „Advanced R, 2nd edition” tutaj .

S4

  • Funkcjonalne podejście OOP.
  • Trzeci najważniejszy system według Hadleya.
  • Przepisz S3, a zatem podobny do S3, ale bardziej formalny i bardziej rygorystyczny: zmusza cię to do dokładnego przemyślenia projektu programu. Nadaje się do budowy dużych systemów (np. Projekt Bioconductor ).
  • Zaimplementowany w podstawowym pakiecie "Methods".
  • Patrz: Chambers, John M. 1998. „Programming with Data: A Guide to the S Language”. Skoczek.
  • Szczegóły w „Advanced R, 2nd edition” tutaj .

RC, czyli „Klasy referencyjne”

  • Zamknięte podejście OOP.
  • Pochodzi z podstawą R.
  • Na podstawie S4.
  • Obiekty RC są specjalnym typem obiektów S4, które również są „modyfikowalne”. tj. zamiast używać zwykłej semantyki języka R typu „kopiuj przy modyfikacji”, można je modyfikować w miejscu. Zauważ, że stan zmienny jest trudny do rozważenia i jest źródłem brzydkich błędów, ale może prowadzić do bardziej wydajnego kodu w niektórych aplikacjach.

R6

  • Zamknięte podejście OOP.
  • Drugi najważniejszy system według Hadleya.
  • Można go znaleźć w pakiecie R6 (zainstaluj za pomocą library(R6))
  • Podobna do RC, ale lżejszy i znacznie szybciej: to nie zależy od S4 lub metod opakowaniu. Zbudowany w oparciu o środowiska R. Też ma:
    • metody publiczne i prywatne
    • aktywne powiązania (pola, które po uzyskaniu dostępu faktycznie wywołują metodę)
    • dziedziczenie klas, które działa między pakietami
    • obie metody klasy (kod, który należy do klasy i ma dostęp poprzez instancję self, private, super) oraz funkcje składowe (funkcje przypisane do pól, które nie są jednak metody, funkcje Just)
  • Zapewnia ustandaryzowany sposób ucieczki przed semantyką „kopiuj przy modyfikacji” języka R
  • Zobacz witrynę z pakietami: „R6: Hermetyzowane programowanie obiektowe dla języka R” .
  • Szczegóły w „Advanced R, 2nd edition” tutaj .

Inni

Istnieją inne, takie jak R.oo (podobne do RC), proto (oparte na prototypach, myślę, że JavaScript) i Mutatr . Jednak „Advanced R” mówi:

Oprócz R6, który jest szeroko stosowany, systemy te są przedmiotem zainteresowania przede wszystkim teoretycznego. Mają swoje mocne strony, ale niewielu użytkowników języka R zna je i rozumie, więc innym osobom trudno jest czytać i współtworzyć Twój kod.

Koniecznie przeczytaj także rozdział poświęcony kompromisom w „Advanced R, wydanie 2” .

David Tonhofer
źródło