R'de "S3 yöntemleri" ne anlama geliyor?


125

R konusunda oldukça yeni olduğum için S3 yöntemlerinin ve nesnelerinin ne olduğunu bilmiyorum. S3 ve S4 nesne sistemleri olduğunu buldum ve bazıları mümkünse S3 üzerinden S4 kullanılmasını öneriyor ( http://google-styleguide.googlecode.com/svn/trunk/google-r-style adresindeki Google'ın R Stil Kılavuzu'na bakın . html ) *. Ancak, S3 yöntemlerinin / nesnelerinin tam tanımını bilmiyorum.

Güncelleme: 2019 itibarıyla Google'ın R Stil Kılavuzu köprüsü artık burada .

Yanıtlar:


85

İlgili bilgilerin çoğu ?S3veya ?UseMethodkısmına bakarak bulunabilir , ancak özetle:

S3, bir yöntem gönderme şemasını ifade eder. Bir süre R kullandıysanız print, birçok farklı nesne türü predictve summaryyöntemleri olduğunu fark edeceksiniz .

S3'te bu şu şekilde çalışır:

  • ilgilenilen nesnelerin sınıfını ayarlama (örneğin: yönteme yapılan bir çağrının dönüş değeri glmsınıfı vardır glm)
  • Genel adıyla (örneğin bir yöntem sağlayarak printdaha sonra), bir nokta ve sınıfadı (örneğin print.glm)
  • Bunun çalışması için bu genel ada ( print) bazı hazırlıkların yapılmış olması gerekir , ancak yalnızca mevcut yöntem adlarına uymak istiyorsanız, buna ihtiyacınız yoktur (eğer yaparsanız daha önce bahsettiğim yardıma bakın ).

Bakanın gözünde ve özellikle, yeni oluşturulan korkak model oturtma paketinin kullanıcı, çok daha rahat yazabilmek olmaktır için predict(myfit, type="class")daha predict.mykindoffit(myfit, type="class").

Biraz daha fazlası var, ama bu başlamanıza yardımcı olmalı. Nesnelerin bir niteliğine (sınıfına) dayalı yöntemlerin bu yolla gönderilmesinin epeyce dezavantajı vardır (ve C safçıları muhtemelen geceleri dehşet içinde uyanık kalırlar), ancak pek çok durumda düzgün çalışır. R'nin mevcut sürümüyle, daha yeni yollar (S4 ve referans sınıfları) uygulandı, ancak çoğu insan hala (yalnızca) S3 kullanıyor.


55

S3'e başlamak için medianişlev koduna bakın . medianKomut istemine yazmak , gövdesinde bir satır olduğunu ortaya çıkarır.

UseMethod("median")

Bu bir S3 yöntemi olduğu anlamına gelir. Diğer bir deyişle, medianfarklı S3 sınıfları için farklı bir işleve sahip olabilirsiniz . Olası tüm medyan yöntemlerini listelemek için yazın

methods(median) #actually not that interesting.  

Bu durumda, herhangi bir şey için çağrılan, varsayılan olan tek bir yöntem vardır. Bunun kodunu yazarak görebilirsiniz

median.default

Çok daha ilginç bir örnek, printbirçok farklı yöntemi olan işlevdir.

methods(print)  #very exciting

Bazı yöntemlerin *adlarının yanında " işareti" olduğuna dikkat edin . Bu, bazı paketlerin ad alanının içine gizlendikleri anlamına gelir. findHangi paketin içinde olduklarını bulmak için kullanın . Örneğin

find("acf")  #it's in the stats package
stats:::print.acf

39

Http://adv-r.had.co.nz/OO-essentials.html adresinden :

R'nin üç OO sistemi, sınıfların ve yöntemlerin nasıl tanımlandığına göre farklılık gösterir:

  • S3, genel işlevli OO adı verilen bir OO programlama stili uygular. Bu, mesaj ileten OO'yu uygulayan Java, C ++ ve C # gibi çoğu programlama dilinden farklıdır. Mesaj geçirme ile, mesajlar (yöntemler) nesnelere gönderilir ve nesne, hangi işlevi çağıracağını belirler. Tipik olarak, bu nesnenin yöntem çağrısında özel bir görünümü vardır ve genellikle yöntemin / mesajın adından önce görünür: örneğin canvas.drawRect ("mavi"). S3 farklıdır. Hesaplamalar hala yöntemler aracılığıyla yürütülürken, genel işlev adı verilen özel bir işlev türü, hangi yöntemin çağrılacağına karar verir, örneğin, drawRect (canvas, "blue"). S3 çok rahat bir sistemdir. Sınıfların resmi bir tanımı yoktur.

  • S4, S3'e benzer şekilde çalışır, ancak daha resmidir. S3 ile iki büyük fark vardır. S4, her sınıf için temsil ve kalıtımı tanımlayan resmi sınıf tanımlarına ve jenerikleri ve yöntemleri tanımlamak için özel yardımcı işlevlere sahiptir. S4 ayrıca birden fazla gönderime sahiptir; bu, genel işlevlerin yalnızca bir değil, herhangi bir sayıda argümanın sınıfına göre yöntem seçebileceği anlamına gelir.

  • Kısaca RC olarak adlandırılan referans sınıfları, S3 ve S4'ten oldukça farklıdır. RC, mesaj ileten OO'yu uygular, bu nedenle yöntemler işlevlere değil sınıflara aittir. $, nesneleri ve yöntemleri ayırmak için kullanılır, bu nedenle yöntem çağrıları canvas $ drawRect ("mavi") gibi görünür. RC nesneleri de değiştirilebilir: R'nin her zamanki değiştirme üzerine kopyalama anlamını kullanmazlar, ancak yerinde değiştirilirler. Bu, akıl yürütmelerini zorlaştırır, ancak S3 veya S4 ile çözülmesi zor sorunları çözmelerine olanak tanır.

Tam olarak OO olmayan başka bir sistem daha var, ancak burada bahsetmek önemlidir:

  • temel türleri, diğer OO sistemlerinin altında yatan dahili C düzeyi türleri. Temel türleri çoğunlukla C kodu kullanılarak manipüle edilir, ancak diğer OO sistemleri için yapı taşları sağladıkları için bilinmesi önemlidir.

12

Bu soruya çoğunlukla isimlerin nereden geldiğini merak ederek geldim. Çıkan sonuca bu wikipedia makalesinde adı R dayandığını Dili Programlama S sürümüne kastediliyor. Diğer cevaplarda açıklanan yöntem gönderme şemaları S'den gelir ve sürüme göre uygun şekilde etiketlenir.


10

Deneyin

methods(residuals)

burada, diğerleri arasında "residuals.lm" ve "residuals.glm" listelenir. Bu, doğrusal bir model, m ve tip taktığınızdaresiduals(m), residuals.lm aranacak. Genelleştirilmiş bir doğrusal model taktığınızda, residuals.glm çağrılacaktır. Bir tür C ++ nesne modeli ters döndü. C ++ 'da, türetilmiş sınıflandırılmış tarafından geçersiz kılınan sanal işlevlere sahip bir temel sınıf tanımlarsınız. R'de bir sanal (aka jenerik) işlev tanımlarsınız ve sonra hangi sınıfların bu işlevi geçersiz kılacağına karar verirsiniz (diğer bir deyişle bir yöntem tanımlayın). Bunu yapan sınıfların ortak bir süper sınıftan türetilmesine gerek olmadığını unutmayın. Genel olarak S4 yerine S3'ü tercih etmeyi kabul etmiyorum. S4'ün daha fazla formalizmi vardır (= daha fazla yazım) ve bu bazı uygulamalar için çok fazla olabilir. Ancak S4 sınıfları, C ++ 'da bir sınıf veya yapı gibi tanımlanabilir. Belirli bir sınıftaki bir nesnenin bir dizeden ve iki sayıdan oluştuğunu belirtebilirsiniz, örneğin:

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

Bu sınıfın bir nesnesiyle çağrılan yöntemler, bu üyelere sahip nesneye güvenebilir. Bu, bir grup öğenin bir listesi olan S3 sınıflarından çok farklı.

S3 ve S4 ile, bir üye işlevini by fun(object, args)değil tarafından çağırırsınız object$fun(args). İkincisi gibi bir şey arıyorsanız, proto paketine bir göz atın.


Nesnelere ait üye işlevler ve yöntemler fikrinin R'de pek bir anlam ifade etmediğinden oldukça eminim. Yöntemler nesnelere ait değildir (işlevler de nesnedir), ancak işleve aittir.
petermeissner

3

İşte bir hızlı sayısız ait yıkık güncellenirsiniz R nesne sistemlerine göre "Gelişmiş Ar, 2. baskı" bir web temsilini vardır Hadley Wickham (RStudio Baş Scientist) tarafından (CRC Press, 2019) burada yaklaşık bölümüne dayanarak, Nesne -O Odaklı Programlama .

Gelişmiş R kitap kapağı

2015'ten itibaren ilk baskının burada bir web sunumu var , burada OO ile ilgili ilgili bölüm var .

OO sistemlerine yaklaşımlar

Hadley, OO programlamasına yönelik iki farklı yaklaşımı ayırt etmek için aşağıdakileri tanımlar:

İşlevsel OOP : yöntemler (çağrılabilir kod parçaları) genel işlevlere aittir (Java / C # jenerik yöntemlerle karıştırılmamalıdır ). Yöntemleri genel bir arama tablosunda yer alıyormuş gibi düşünün. Çalıştırılacak yöntem, çalışma zamanı sistemi tarafından, işlevin adına ve bu işleve iletilen bir veya daha fazla argümanın türüne (veya nesne sınıfına) göre bulunur (buna "yöntem dağıtımı" denir). Söz dizimi-bilge, yöntem çağrıları sıradan fonksiyon çağrıları gibi görünebilir: myfunc(object, arg1, arg2). Bu çağrı, çalışma zamanının çiftle ilişkili yöntemi ("işlevim", typeof (nesne)) veya muhtemelen ("işlevim", typeof (nesne), typeof (arg1), typeof (arg2)) aramasına yol açar.dil destekliyorsa. R'nin S3'ünde, genel işlevin tam adı (işlev adı, sınıf) çiftini verir. Örneğin: mean.DateTarihlerin ortalamasını hesaplama yöntemidir. methods("mean")Fonksiyon adıyla genel yöntemleri listelemeye çalışın mean. Fonksiyonel OOP yaklaşımı örneğin OO öncüsü Smalltalk , Common Lisp Nesne Sistemi ve Julia'da bulunur . Hadley, "R ile karşılaştırıldığında, Julia'nın uygulamasının tamamen gelişmiş ve son derece performanslı olduğunu " belirtiyor .

Kapsüllenmiş OOP : yöntemler nesnelere veya sınıflara aittir ve yöntem çağrıları genellikle benzer object.method(arg1, arg2). Bu, kapsüllenmiş olarak adlandırılır çünkü nesne hem verileri (alanları) hem de davranışı (yöntemleri) kapsamaktadır. Yöntemin, nesneye veya nesnenin sınıf açıklamasına eklenmiş bir arama tablosunda yer aldığını düşünün. Çalışma zamanı yöntemi, yöntem adına ve muhtemelen bir veya daha fazla argümanın türüne göre arar. Bu, C ++, Java, C # gibi "popüler" OO dillerinde bulunan yaklaşımdır.

Her iki durumda da, eğer miras destekleniyorsa (muhtemelen desteklenmektedir), çalışma zamanı, arama arama anahtarı için bir eşleşme bulana kadar sınıf hiyerarşisini yukarı doğru hareket ettirebilir.

Bir R nesnesinin hangi sisteme ait olduğunu bulma

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

R nesne sistemleri

S3

  • Fonksiyonel OOP yaklaşımı.
  • Hadley'e göre en önemli sistem.
  • En basit, en yaygın. R. tarafından kullanılan ilk OO sistemi
  • R tabanı boyunca kullanılan R tabanı ile birlikte gelir.
  • Zorunlu garantilerden çok sözleşmelere dayanır.
  • Bkz Chambers, John E, ve Trevor J Hastie. 1992. "S.'de İstatistiksel Modeller" Wadsworth & Brooks / Cole Gelişmiş Kitaplar ve Yazılım.
  • Ayrıntılar "Gelişmiş Ar, 2. baskı" Burada .

S4

  • Fonksiyonel OOP yaklaşımı.
  • Hadley'e göre üçüncü en önemli sistem.
  • S3'ün yeniden yazılması, bu nedenle S3'e benzer, ancak daha resmi ve daha katıdır: sizi program tasarımı hakkında dikkatlice düşünmeye zorlar. Büyük sistemler oluşturmak için uygundur (örn. Bioconductor projesi).
  • Temel "yöntemler" paketinde uygulanır.
  • Bakınız: Chambers, John M. 1998. "Verilerle Programlama: S Dili Rehberi." Springer.
  • Ayrıntılar "Gelişmiş Ar, 2. baskı" Burada .

RC aka "Referans Sınıfları"

  • Kapsüllenmiş OOP yaklaşımı.
  • Baz R ile birlikte gelir.
  • S4'e göre.
  • RC nesneleri, aynı zamanda "değiştirilebilir" olan özel S4 nesneleridir. yani, R'nin olağan değiştirildiğinde kopyala semantiğini kullanmak yerine, yerinde değiştirilebilirler. Değişken durumun mantık yürütmek zor olduğunu ve çirkin hataların kaynağı olduğunu, ancak bazı uygulamalarda daha verimli koda yol açabileceğini unutmayın.

R6,

  • Kapsüllenmiş OOP yaklaşımı.
  • Hadley'e göre ikinci en önemli sistem.
  • Bulunabilir R6 paketi (ile yüklemek library(R6))
  • RC'ye benzer, ancak daha hafif ve çok daha hızlı: S4'e veya yöntemlere bağlı değildir paketine . R ortamları üzerine inşa edilmiştir. Ayrıca şunları içerir:
    • genel ve özel yöntemler
    • etkin bağlamalar (erişildiğinde aslında bir yöntemi çağıran alanlar)
    • Paketler arasında çalışan sınıf kalıtımı
    • Her iki sınıf yöntemleri (sınıfına aittir ve aracılığıyla bir örneği erişebilirler kodu self, private, super) ve üye fonksiyonları (alanlarına atanan fonksiyonlar ancak yöntemler hangilerinin sadece fonksiyonlar)
  • R'nin "değiştirildiğinde kopyala" anlamından kaçmak için standart bir yol sağlar
  • Paket sitesine bakın: "R6: R için kapsüllenmiş nesne yönelimli programlama" .
  • Ayrıntılar "Gelişmiş Ar, 2. baskı" Burada .

Diğerleri

Gibi başkaları vardır R.oo (RC benzer), proto (prototip tabanlı, JavaScript düşünün) ve Mutatr . Ancak, "Gelişmiş R" şunu söylüyor:

Yaygın olarak kullanılan R6 dışında, bu sistemler öncelikle teorik olarak ilgi çekicidir. Onların güçlü yanları vardır, ancak çok az R kullanıcısı bunları bilir ve anlar, bu nedenle başkalarının kodunuzu okuması ve katkıda bulunması zordur.

Faslını mutlaka okuyun dengeler içinde "Gelişmiş Ar, 2. baskı" da.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.