136

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

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

4

6 に答える 6

90

?S3関連情報のほとんどは、またはを見るとわかりますが?UseMethod、簡単に言うと次のようになります。

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

S3では、これは次のように機能します。

  • 対象のオブジェクトのクラスを設定します(例:メソッドの呼び出しの戻り値にglmはクラスがありますglm
  • メソッドに一般名(例print)、ドット、クラス名(例:)の順に指定します print.glm
  • これを機能させるには、この一般名()に対していくつかの準備を行うprint必要がありますが、単に既存のメソッド名に準拠することを検討している場合は、これは必要ありません(以前に参照したヘルプを参照してください)。 )。

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

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

于 2011-07-05T13:44:53.403 に答える
55

S3の使用を開始するには、median関数のコードを確認してください。コマンドプロンプトで入力medianすると、本文に1行あることがわかります。

UseMethod("median")

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

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
于 2011-07-05T14:05:59.757 に答える
39

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

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

  • S3は、ジェネリック関数OOと呼ばれるオブジェクト指向プログラミングのスタイルを実装します。これは、メッセージパッシングオブジェクト指向を実装するJava、C ++、C#などのほとんどのプログラミング言語とは異なります。メッセージパッシングでは、メッセージ(メソッド)がオブジェクトに送信され、オブジェクトが呼び出す関数を決定します。通常、このオブジェクトはメソッド呼び出しで特別な外観を持ち、通常はメソッド/メッセージの名前の前に表示されます(例: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の通常のcopy-on-modifyセマンティクスを使用しませんが、その場で変更されます。これにより、彼らは推論するのが難しくなりますが、S3またはS4では解決するのが難しい問題を解決することができます。

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

  • 基本タイプ、他のOOシステムの基礎となる内部Cレベルタイプ。基本タイプは主にCコードを使用して操作されますが、他のOOシステムの構成要素を提供するため、知っておくことが重要です。
于 2014-05-20T18:58:48.553 に答える
12

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

于 2011-11-01T23:11:30.417 に答える
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パッケージをご覧ください。

于 2011-07-05T23:22:42.647 に答える
3

これは、オブジェクトに関する章に基づいて、ここにWeb表現があるHadley Wickham(RStudioのチーフサイエンティスト)による「AdvancedR、2nd edition」(CRC Press、2019)による多数のRオブジェクトシステムの更新された高速要約です。 -指向プログラミング

アドバンストRブックカバー

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

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

Hadleyは、オブジェクト指向プログラミングへの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 SystemJuliaに見られます。Hadleyは、「Rと比較して、Juliaの実装は完全に開発されており、非常にパフォーマンスが高い」と述べています。

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

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

Rオブジェクトがどのシステムに属しているかを確認する方法

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

Rオブジェクトシステム

S3

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

S4

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

RC別名「リファレンスクラス」

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

R6

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

その他

R.oo(RCに似ている)、proto(プロトタイプベース、JavaScriptだと思う)、Mutatrなどの他にもあります。ただし、「AdvancedR」は次のように述べています。

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

「AdvancedR、第2版」のトレードオフの章も必ずお読みください。

于 2019-10-26T11:29:20.167 に答える