2011-07-05 14 views
90

私はRにかなり新しいので、私はS3のメソッドとオブジェクトが何であるか分かりません。 S3とS4のオブジェクトシステムがあることがわかりました。また、可能であればS3を使用することをおすすめしています(http://google-styleguide.googlecode.com/svn/trunk/google-r-style.html)。しかし、私はS3メソッド/オブジェクトの正確な定義を知らない。Rで「S3メソッド」とは何を意味していますか?

答えて

65

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

S3は、メソッドのディスパッチの仕組みを指します。 Rをしばらく使用した場合、多くの種類のオブジェクトに対して、printpredictsummaryのメソッドがあることに気づくでしょう。

S3では

、これはで動作します。

関心(例:クラス glmを持って glm方法に 呼び出しの戻り値)のオブジェクトのクラス設定
  • と方法を提供する
  • を一般その後、 名(例:print)、ドット、および その後、クラス名(例: print.glm
  • いくつかの準備は01となっている必要がありは仕事に、この一般的な名前(print)このため に行われていますが、 は、単に 既存のメソッド名に自分を適合するように探しているなら、あなたは この(もしあれば、私は以前 に参照さヘルプを参照してくださいする必要はありません。行う)。見る人の目に

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

これ以上のことはありますが、これが始めるはずです。オブジェクトの属性(クラス)に基づいてメソッドをディスパッチするこの方法には、いくつかの欠点があります(おそらく、Cの純粋主義者はおそらく夜間に目を覚ますでしょう)。しかし、多くの状況ではうまく動作します。現在のバージョンのRでは、より新しい方法(S4と参照クラス)が実装されていますが、ほとんどの人はまだS3を使用しています。

37

S3を使い始めるには、median関数のコードを見てください。コマンドプロンプトでmedianを入力すると、それはS3方法であることを意味し、すなわち

UseMethod("median") 

その本体の1本のラインを有していることがわかります。つまり、S3クラスごとに異なるmedian関数を持つことができます。すべての可能な中央のメソッド、この場合、タイプ

methods(median) #actually not that interesting. 

を一覧表示するには、何のために呼ばれている唯一の方法は、デフォルトでは、あります。あなたははるかに興味深い例は、多くの異なる方法がありprint機能、ある

median.default 

を入力して、そのためのコードを見ることができます。

methods(print) #very exciting 

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

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

中でも、 "residuals.lm" と "residuals.glm"、一覧表示され

methods(residuals) 

を試してみてください。これは、線形モデルmをフィッティングしてresiduals(m)と入力すると、residuals.lmが呼び出されることを意味します。一般化線形モデルをフィッティングすると、residuals.glmが呼び出されます。 C++のオブジェクトモデルが逆さまになっています。 C++では、派生クラスによってオーバーライドされる仮想関数を持つ基本クラスを定義します。 Rでは、仮想(別名汎用)関数を定義し、この関数をオーバーライドするクラスを定義します(別名メソッドの定義)。これを行うクラスは、共通のスーパークラスから派生する必要はないことに注意してください。 私は一般的にS3よりもS3を好むことに同意しません。 S4にはより多くの形式化(=より多くの型付け)があり、これはアプリケーションによっては多すぎるかもしれません。しかし、S4クラスはC++のクラスや構造体のように定義することができます。そのクラスのオブジェクトで呼び出され

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

の方法は、それらのメンバーを持つオブジェクトに頼ることができます:あなたは、特定のクラスのオブジェクトは、例えば、文字列と2つの数の構成されていることを指定することができます。これはS3クラスとは非常に異なります.S3クラスは単なる要素のリストです。

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

+0

私はオブジェクトに属するメンバ関数やメソッドのアイデアはR.方法ではあまり意味がオブジェクトに属している(また、機能があまりにもオブジェクトである)が、機能に属していないことを確認しないことをかなり確信しています。 – petermeissner

+0

[ここをクリック](http://adv-r.had.co.nz/OO-essentials.html#s3) – petermeissner

10

名前がどこから来たのかという疑問が出てきました。 this wikipedia articleから、名前がRが基づいているSプログラミング言語のバージョンを参照するように見えます。他の回答に記述されているメソッドディスパッチスキームはSから来て、バージョンに応じて適切にラベル付けされています。 http://adv-r.had.co.nz/OO-essentials.htmlから

27

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

  • S3は、一般的な機能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の通常のコピー・オン・モディファイ・セマンティクスは使用されませんが、 が変更されています。これにより、彼らは推論するのが難しくなりますが、 は、S3またはS4で解決するのが難しい問題を解決することができます。

ありかなりOOではありません一つの他のシステムもありますが、それはここで言及する 重要です。

  • ベースタイプ、他のOO システムの基礎となる内部のCレベルのタイプを。基本タイプはCコードを使用して処理されることがほとんどですが、 の他のOOシステムのビルディングブロックを提供しているので、これはよく知っておいてほしい です。
関連する問題