Rで「S3メソッド」とはどういう意味ですか?


124

私はRにかなり慣れているので、S3メソッドとオブジェクトが何であるかわかりません。S3とS4のオブジェクトシステムがあり、可能であればS4よりもS3を使用することをお勧めします(http://google-styleguide.googlecode.com/svn/trunk/google-r-styleにある GoogleのRスタイルガイドを参照してください。 html)*。しかし、私はS3メソッド/オブジェクトの正確な定義を知りません。

更新:2019年現在、GoogleのRスタイルガイドのハイパーリンクがここにあります

回答:


85

関連情報のほとんどは、?S3またはを見ることで見つけることができます?UseMethodが、一言で言えば:

S3はメソッドディスパッチのスキームを指します。しばらくRを使用したことがある場合はprint、さまざまな種類のオブジェクトにpredictsummaryメソッドがあることに気付くでしょう。

S3では、これは次の方法で機能します。

  • 対象となるオブジェクトのクラスを設定します(例:メソッドの呼び出しの戻り値にglmはclassがありますglm
  • 一般的な名前(例えばとメソッドを提供printドット、その後、クラス名(例:その後、) print.glm
  • printこれを機能させるには、この一般的な名前()を準備しておく必要がありますが、既存のメソッド名に自分自身を合わせるだけの場合は、これは必要ありません(行う場合は、前に参照したヘルプを参照してください)。 )。

見る人、特に新しく作成したファンキーなモデルフィッティングパッケージのユーザーの目には、を入力するpredict(myfit, type="class")よりもはるかに便利ですpredict.mykindoffit(myfit, type="class")

これにはかなり多くの機能がありますが、これで開始できます。オブジェクトの属性(クラス)に基づいてメソッドをディスパッチするこの方法には、いくつかの欠点があります(Cの純粋主義者は恐らく夜に目を覚まし、恐怖を感じます)が、多くの状況では、きちんと機能します。Rの現在のバージョンでは、新しい方法(S4および参照クラス)が実装されていますが、ほとんどの人はまだ(のみ)S3を使用しています。


54

S3を使い始めるには、median関数のコードを見てください。タイピングmedianコマンドプロンプトでは、それはすなわち、その本体内の1つのラインを持っていることが明らかになりました

UseMethod("median")

つまり、これはS3メソッドです。つまり、medianS3クラスごとに異なる機能を持つことができます。考えられるすべての中央値法を一覧表示するには、次のように入力します。

methods(median) #actually not that interesting.  

この場合、デフォルトのメソッドが1つだけあり、これは何でも呼び出されます。次のように入力すると、そのコードが表示されます

median.default

さらに興味深い例は、print関数で、さまざまな方法があります。

methods(print)  #very exciting

一部のメソッドには*、名前の横にs があることに注意してください。つまり、それらはいくつかのパッケージの名前空間の中に隠されています。findそれらが入っているパッケージを見つけるために使用します。例えば

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

39

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

Rの3つのOOシステムは、クラスとメソッドの定義方法が異なります。

  • S3は、ジェネリックファンクションOOと呼ばれるOOプログラミングのスタイルを実装しています。これは、Java、C ++、C#など、メッセージパッシングOOを実装するほとんどのプログラミング言語とは異なります。メッセージパッシングでは、メッセージ(メソッド)がオブジェクトに送信され、オブジェクトが呼び出す関数を決定します。通常、このオブジェクトはメソッド呼び出しで特別な外観を持ち、通常はメソッド/メッセージの名前の前に表示されます(例:canvas.drawRect( "blue"))。S3は異なります。計算は依然としてメソッドを介して実行されますが、総称関数と呼ばれる特別なタイプの関数が、どのメソッドを呼び出すかを決定します(例:drawRect(canvas、 "blue"))。S3は非常にカジュアルなシステムです。クラスの正式な定義はありません。

  • S4はS3と同様に機能しますが、より正式です。S3には2つの大きな違いがあります。S4には、各クラスの表現と継承を記述する正式なクラス定義があり、ジェネリックスとメソッドを定義するための特別なヘルパー関数があります。S4には複数のディスパッチもあります。つまり、ジェネリック関数は、1つだけでなく、任意の数の引数のクラスに基づいてメソッドを選択できます。

  • 略してRCと呼ばれる参照クラスは、S3およびS4とはかなり異なります。RCはメッセージパッシングOOを実装しているため、メソッドは関数ではなくクラスに属します。$はオブジェクトとメソッドを分離するために使用されるため、メソッド呼び出しはcanvas $ drawRect( "blue")のようになります。RCオブジェクトも変更可能です。Rオブジェクトは通常のRのcopy-on-modifyセマンティクスを使用しませんが、適切に変更されます。これにより、論理的な理由がわかりにくくなりますが、S3またはS4では解決が難しい問題を解決することができます。

OOではないシステムがもう1つありますが、ここで言及することが重要です。

  • 基本タイプ。他のOOシステムの基礎となる内部Cレベルのタイプ。基本型は主にCコードを使用して操作されますが、他のOOシステムにビルディングブロックを提供するため、知っておくことが重要です。

11

私はこの質問に来て、名前はどこから来たのだろうと思いました。このウィキペディアの記事から、その名前はRのベースとなっているSプログラミング言語のバージョンを指しているように見えます。他の回答で説明されているメソッドディスパッチスキームはSからのものであり、バージョンに応じて適切にラベル付けされています。


10

試す

methods(residuals)

特に、「residuals.lm」と「residuals.glm」をリストします。これは、線形モデル、m、およびタイプを当てはめたときresiduals(m)、residuals.lmが呼び出されます。一般化線形モデルをフィッティングすると、residuals.glmが呼び出されます。これは、C ++オブジェクトモデルをひっくり返したようなものです。C ++では、仮想クラスを持つ基本クラスを定義します。仮想クラスは、派生クラスによってオーバーライドされます。Rでは、仮想(別名ジェネリック)関数を定義してから、この関数をオーバーライドするクラス(別名メソッドの定義)を決定します。これを行うクラスは、1つの共通のスーパークラスから派生する必要がないことに注意してください。私は一般的にS4よりもS3を優先することに同意しません。S4はより形式的(=より多くのタイピング)であり、これは一部のアプリケーションには多すぎるかもしれません。ただし、S4クラスは、C ++のクラスまたは構造体のように定義解除できます。たとえば、特定のクラスのオブジェクトが文字列と2つの数値で構成されるように指定できます。

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

そのクラスのオブジェクトで呼び出されるメソッドは、それらのメンバーを持つオブジェクトに依存できます。これは、一連の要素の単なるリストであるS3クラスとは非常に異なります。

S3とS4では、メンバー関数をfun(object, args)でではなくで呼び出しますobject$fun(args)。後者のようなものを探しているなら、protoパッケージを見てください。


オブジェクトに属するメンバー関数とメソッドの概念は、Rではそれほど意味がないと確信しています。メソッドはオブジェクトに属さず(関数もオブジェクトです)、関数に属しています。
petermeissner

3

オブジェクトに関する章に基づいて、ここにWeb表現がある、Hadley Wickham(RStudioの主任科学者)による「Advanced R、2nd edition」(CRC Press、2019)による多数のRオブジェクトシステムの更新された高速ランダウンを以下に示します-指向プログラミング

Advanced Rブックカバー

2015年の初版には、ここにOOの対応する章がある、ここにWeb表現があります

OOシステムへのアプローチ

Hadleyは、OOプログラミングへの2つの異なるアプローチを区別するために、以下を定義します。

関数型OOP:メソッド(呼び出し可能なコード)は、ジェネリック関数に属します(Java / C#ジェネリックメソッドと混同しないでください)。メソッドは、グローバルルックアップテーブルにあると考えてください。実行するメソッドは、関数の名前と、その関数に渡される1つ以上の引数のタイプ(またはオブジェクトクラス)に基づいて、ランタイムシステムによって検出されます(これは「メソッドディスパッチ」と呼ばれます)。構文的には、メソッド呼び出しは通常の関数呼び出しのようになりますmyfunc(object, arg1, arg2)。この呼び出しは、ペアに関連付けられたメソッド( "myfunc"、typeof(object))またはおそらく( "myfunc"、typeof(object)、typeof(arg1)、typeof(arg2))を探すようにランタイムをリードします。言語がそれをサポートしている場合。RのS3では、総称関数の完全な名前が(関数名、クラス)のペアを示します。例:mean.Dateは、日付の平均を計算するメソッドです。methods("mean")関数名を持つジェネリックメソッドをリストしてみてくださいmean。機能的OOPアプローチは、たとえばOOのパイオニアであるSmalltalkCommon Lisp Object System、およびJuliaにあります。ハドリー氏は、「Rと比較して、Juliaの実装は完全に開発されており、非常に高性能です」と述べています。

カプセル化されたOOP:メソッドはオブジェクトまたはクラスに属し、メソッド呼び出しは通常のようになりobject.method(arg1, arg2)ます。オブジェクトはデータ(フィールド)と動作(メソッド)の両方をカプセル化するため、これはカプセル化と呼ばれます。このメソッドは、オブジェクトまたはオブジェクトのクラスの説明に添付されたルックアップテーブルにあると考えてください。ランタイムは、メソッド名と、場合によっては1つ以上の引数のタイプに基づいてメソッドを検索します。これは、C ++、Java、C#などの「人気のある」オブジェクト指向言語で見られるアプローチです。

どちらの場合も、継承がサポートされている場合(おそらくサポートされている場合)、ランタイムは、呼び出しルックアップキーの一致が見つかるまで、クラス階層を上方向に移動します。

Rオブジェクトが属するシステムを見つける方法

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

Rオブジェクトシステム

S3

  • 機能的なOOPアプローチ。
  • Hadleyによると最も重要なシステム。
  • 最も単純で、最も一般的です。Rが最初に使用したオブジェクト指向システム。
  • ベースR全体に使用されているベースRが付属しています。
  • 強制された保証ではなく規則に依存します。
  • Chambers、John M、およびTrevor J Hastieを参照してください。1992.「S.の統計モデル」Wadsworth&Brooks / Cole Advanced Books&Software。
  • 詳細はこちら「アドバンスドR第2版」

S4

  • 機能的なOOPアプローチ。
  • Hadleyによると、3番目に重要なシステムです。
  • したがって、S3の書き換えはS3に似ていますが、より正式でより厳密です。プログラム設計について慎重に考える必要があります。大規模なシステム(例:バイオコンダクタープロジェクト)の構築に適しています。
  • 基本の「メソッド」パッケージに実装されています。
  • 参照:Chambers、John M.1998。「データを使用したプログラミング:S言語のガイド」。スプリンガー。
  • 詳細はこちら「アドバンスドR第2版」

RC別名「参照クラス」

  • カプセル化されたOOPアプローチ。
  • ベースRが付属しています。
  • S4に基づく。
  • RCオブジェクトはS4オブジェクトの特殊なタイプで、これも「変更可能」です。つまり、Rの通常のcopy-on-modifyセマンティクスを使用する代わりに、インプレースで変更できます。ミュータブルな状態は、醜いバグの原因とその原因を推測することは困難ですが、特定のアプリケーションではより効率的なコードにつながる可能性があることに注意してください。

R6

  • カプセル化されたOOPアプローチ。
  • Hadleyによると、2番目に重要なシステムです。
  • R6パッケージに含まれています(でインストールlibrary(R6)
  • RCに似ていますが、軽量ではるかに高速です。S4やメソッドパッケージに依存しません。R環境の上に構築されています。またあります:
    • パブリックメソッドとプライベートメソッド
    • アクティブなバインディング(アクセスされたときに実際にメソッドを呼び出すフィールド)
    • パッケージ全体で機能するクラスの継承
    • 両方のクラスメソッド(クラスに属するとを介してインスタンスにアクセスすることができるコードselfprivatesuper)とメンバ関数(フィールドに割り当てられた機能が、方法はない、単に機能)
  • Rの「コピーオンモディファイ」セマンティクスをエスケープする標準化された方法を提供します
  • パッケージサイト「R6:Rのカプセル化されたオブジェクト指向プログラミング」を参照してください。
  • 詳細はこちら「アドバンスドR第2版」

その他

以下のような他のもの、ありますR.oo(RCと同様)、プロト(プロトタイプベース、JavaScriptを考える)とMutatrが。ただし、「Advanced R」は次のように述べています。

広く使用されているR6とは別に、これらのシステムは主に理論的に重要です。それらには長所がありますが、それらを知って理解しているRユーザーはほとんどいないため、他のユーザーがコードを読んで貢献することは困難です。

章に必ずお読みくださいトレードオフの中で、「高度なR、第2版」も。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.