問題タブ [s4]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
r - Rの関数switch()を理解していますか?
VenablesとRipleyによって書かれた本「StatisticsandComputing」には、一般的なグループ関数Mathのクラス「polynomial」のオブジェクトでメソッド関数を定義する例があります。数学は、abs、acos、acoshなどのいくつかのコンポーネント関数を含むグループ関数です...
以下は、グループジェネリック関数Mathのメソッド関数を定義するために本で言及されているコードです(コードはS4クラス(新しいスタイルのR / Sクラス)用であることに注意してください)。
setMethod()を使用して、クラス "polynomial"のオブジェクトで呼び出されたときに、ジェネリック関数Mathのメソッド関数を定義していることを理解しています。ここでどのスイッチが機能するか説明していただけますか?スイッチのRヘルプを読みましたが、それでも以下の部分を理解するのに苦労しています。
上記の多項式関数は、クラス「polynomial」のオブジェクトを作成するためのコンストラクター関数であることに注意してください。
r - マトリックスへの S4 R オブジェクトの割り当て: なぜこれが機能するのですか?
という名前の S4 クラスを定義しました。そのcell
インスタンスを 3x3 マトリックスに割り当てたいと考えています (明確にするために 3x3 が選択されています)。次のコードは R バージョン 2.15.1 で機能し、単純なケースで R の動作を再現します。タイプのオブジェクトをマトリックスに割り当てることができることがわかりcell
ました。そのエントリは最初に で空のリストに初期化されmatrix(list(),3,3)
、その後、新しいタイプのオブジェクトをエントリに割り当てcell
ます。問題は、なぜそれが機能するのかということです。
これはサンプル セッションです。
createGrid()
空のリストの割り当てを変更して変更grid<- matrix(0,3,3)
すると、エラーが発生します。
これは驚くべきことではありませんが、動作するコードにたどり着きました。を使用してセルの 3x3 マトリックスを定義しようとする次の試みはnew()
失敗します。
問題は、なぜ最初のものが機能するのかということです。
r - S4オブジェクトコンポジションの誤動作?
次の問題があります(コードは以下にあります):2つのS4クラスがあり、A
とで指定できますB
。このB
クラスには、という名前のAタイプオブジェクトのリストがありますa.list
。A
クラスには、という名前のメソッドがありますtest()
。次に、A
と呼ばれるタイプのオブジェクトとa
、タイプB
のオブジェクトを作成し、そのオブジェクトをのリストb
に挿入します。a
b@a.list
a
オブジェクトを抽出してtest
メソッドを使用すると、次のエラーが発生します。
しかし、私はオブジェクトで直接メソッドを使用しa
、すべてが正常に機能します。
私が間違っていることについて何か考えはありますか?
前もって感謝します
そして今、コード:
再度、感謝します...
r - 関連するオブジェクトからS4参照クラスを定義する実際のソース式を取得する
要するに(実際の質問)
または(実際のソースファイルを調査するのではなく、ソースされた後)によって返されたオブジェクトからS4参照クラス(を参照)を定義する実際のソースコード/式にアクセスするにはどうすればよいですか??setRefClass
getClass("MyClass")
getRefClass("MyClass")
私がした宿題
すべてがRのオブジェクトなので、ソースコード/式を取得できます。
1)それぞれのオブジェクトを調査するだけの通常の機能:
2)特定のメソッドのメソッドオブジェクトを次の方法で取得することによる形式手法selectMethod
:
ただし、S4リファレンスクラスでは状況が異なるようです。
クラスを正確に定義する実際のソースコード/式が格納されている属性が見つからないようです。
念のために言っておきますが、この式は私がアクセスしたいものです
背景/動機
私はS4参照クラス( )をよく使用するため、クラスの継承?setRefClass
などのOOPの側面が日常業務で大きな役割を果たします。また、整理された状態を維持するために「ファイルごとに1つの定義」パラダイムに従います。そのため、さまざまなクラス定義は、ファイル名がそれぞれのクラスの名前に対応する個別のファイルに格納されます。
人生のすべてと同様に、いくつかの利点がありますが、そのようなアプローチにはいくつかの固有の欠点もあります。
アスペクト1
短期間でも長期間でも、個々のソースファイルのアルファベット順のファイル順序と一致しない継承構造になってしまいます。したがって、ファイルを次々にソースするだけでは、必要なスーパークラスがまだソースされていない特定のポイントでエラーが発生します。
class_A.R
はフォルダ内の最初のファイルですが、ソースを作成するには、classes
最初にソースを作成する必要がありますclass_B.R
(このファイルはクラスを定義しているB
ため)。これにはクラスが必要でC
あり、したがって、の事前のソーシングが必要ですclass_C.R
。
したがって、正しい照合は次のようになります。
アスペクト2
特定のタスクでは、「ファイルごとに複数の定義」パラダイムが必要です。パラダイム化するときに必要なオブジェクト/関数/クラスをワーカープロセスにすばやく簡単に配布し、実際にパッケージをビルドするときにコードを整理します。
広告アスペクト1
正しい照合順序を指定するある種の手動照合参照を保持するという考えは、コンピューターが私のために簡単に実行できる(正しい照合を見つける)仕事だと思うので、好きではありません。ここで行う必要があるのは、各クラスのスーパークラス(その依存関係の一種)を見つけることだけです。次に、正しい照合を取得するのは簡単です。
編集
誰かが興味を持った場合:私はこれのための実用的なアプローチを思いついた。コードを見たい場合に備えて、私に連絡してください。contains
これは、スーパークラスをリストする引数の値を調査するために、それぞれのクラスdefソースファイルを(評価せずに)解析することに基づいています。その後、最終的に正しい照合が行われるまで、これらのスーパークラスのソースファイルに対してプロセス全体が再帰的に繰り返されます。それほど時間もかかりません。
概要は次のとおりです。
広告アスペクト2
また、手動でのコピーと貼り付けも好きではないので、個々のファイルに保存されているか、それぞれのオブジェクトから描画されたソースコードを単一の「統合」ファイルに統合できるルーチンを実装しました(およびを介しdeparse(<source_code_expression>)
てwrite(..., append=TRUE)
)。クラスに関しては、ここでも正しい照合が重要です。そうでない場合、統合ファイルを入手しようとすると、再びエラーが発生します。
どちらの側面でも、クラス/関数/メソッドの実際のソースコード/式にアクセスする方法を選択できると便利です。
- それぞれのソースファイルに保存されているコードの調査に基づく(
parse(file=*)
) - または、それぞれのオブジェクトから直接必要な情報にアクセスすることに基づいています。
2番目のオプションは、上記の実際の質問へのリンクです。
r - コンテンツを目的のオブジェクトに保存する
私はこのようなベクトルを持っています:
私はこのような別のベクトルを持っています:
ここで私がやろうとしているのは、RDataファイルをロードしてから、同じファイル名で保存し直すことですが、オブジェクトはvec1のオブジェクトである必要があります。
"incompatible types"
しかし、次のようにキャラクターオブジェクトのクラスも変更しようとしたというエラーが表示されます。
ここで、myclassはS4タイプのオブジェクトのクラスです。
Rでこれを行う方法はありますか?
r - R でのオブジェクト指向プログラミングの学習に役立つ本はありますか?
「 S4 クラスを使用した R のオブジェクト指向プログラミング」に関する R ブロガーの興味深い投稿を読んでいました。Venables と Ripley によって書かれた本「Statistics and Computing」には、S と R の S3 クラスと S4 クラスを紹介するいくつかの章があり、 R でのオブジェクト指向プログラミングの概念を理解するのに役立ちました。
R ブロガーに掲載されているような例を使用して、R でのオブジェクト指向プログラミングを詳しく紹介している有用な本を知っていますか?
r - .rd ファイルで S4 メソッドにリンクしていますか?
私は S4 クラスを含むパッケージを作成しており、クラスのメソッドとas.POSIXct
クラスのメソッドを作成しas.POSIXlt
ました。私はドキュメントを作成しましたが、すべて問題ないように見えますが、as.POSIXct
のドキュメントでメソッドを参照したいas.POSIXlt
場合と、その逆の場合を除きます。\S4method{coerce}{abc, POSIXct}(from, to)
、(「abc」はS4クラスです)を試しましたが\usage
、それはセクションにのみ配置することになっていますが、それは私が望む場所ではありません。これを行う方法はありますか?それが許されないというのは奇妙に思えます。
これらの .rd ファイルを組み合わせてこの問題を回避できることはわかっていますが、R のクラスとパッケージについてできるだけ多くのことを学ぼうとしているので、とにかくこれは興味深いことです。
.Rd ファイルの 1 つのスケルトンを次に示します。
下から 4 番目の行が問題を引き起こしている行です。
r - S4 メソッドと S3 メソッドを 1 つの関数に組み合わせる
S3 クラスと S4 クラスの両方を実装する必要がある汎用関数を定義する良い方法は何ですか? 私はこのようなものを使用しています:
これは成功します:
これを達成するための「ネイティブ」な方法はありますか?を使用して S3 クラスの S4 メソッドを定義できることはわかっていますがsetOldClass
、この方法では、オブジェクトに複数のクラスがある場合に S3 メソッドのディスパッチが失われます。例 (クリーン セッションの場合):
の 2 番目のクラス (object
この場合bar
は ) が無視されるため、これは失敗します。foo
と の間で正式な S4 継承を定義することでおそらくこれを修正できますbar
が、私のアプリケーションではmyfun.bar
、 class を使用して S3 オブジェクトをそのまま使用したいと考えていますbar
。
いずれにせよ、物事は混乱しています。これは一般的な問題だと思います。おそらくこれを行うためのより良い方法がありますか?
r - 形式手法の定義を使用したS3オブジェクトのS3スタイルのディスパッチ
この質問に関連していますが、少し異なり、うまくいけばもっと明確になります。
私は、S4クラスとS3クラスの両方のメソッドを正式に登録するためのクリーンな方法を探していますが、ディスパッチするためにひどいS3-dot-naming-schemeに依存することはありません。例:
この例は、関数に名前を付ける必要なしに、test
クラスのS3オブジェクトのメソッドを登録する方法を示しています。これはすばらしいことです。ただし、この方法でメソッドを登録すると、オブジェクトの最初のS3クラスにのみディスパッチされるという制限があります。例えば:bar
test.bar
foo
S4メソッドディスパッチはクラスとそのスーパークラスのみを試行するため、これは機能しません。この例を拡張して、適切なメソッドが見つからなかった場合にtest
メソッドを自動的に選択するようにするにはどうすればよいでしょうか。たとえば、S3スタイルのディスパッチですが、すべての名前付けに戻る必要はありませんか?bar
foo
test.foo
test.bar
要約すると、形式手法ディスパッチを使用するジェネリック関数を作成する方法ですが、さらに、複数のクラスを持つS3オブジェクトのオブジェクトの2番目、3番目などのクラスにフォールバックします。
r - `getClasses()` のデフォルト環境のあいまいなバリエーション (標準関数と正式な S4 メソッド)
「環境の入れ子」/字句スコープに関して、ここで正確に何が起こっているのかを理解するのに苦労しています:
問題
where
関数内の引数のデフォルト値は、標準の R 関数内で呼び出されるか、正式な S4 メソッドgetClasses()
内で呼び出されるかによって異なるようです。遅延評価の「オブジェクト」と思われるものによって制御されるため、バリエーションが発生します(以下の編集を参照)getClasses()
.externalCallerEnv()
質問
正式な S4 メソッド内から呼び出された場合、標準関数内で呼び出されたwhere
ときのデフォルト値と同じ値に設定するにはどうすればよいですか?getClasses()
図
以下に、上記の「問題のある動作」の簡単な図を示します。
1) カスタムクラス
現在ソースになっているクラス定義が多数あり.GlobalEnv
ます。
これをすべての代表として取り上げましょう
2) 利用可能なクラスの一覧表示
where
関数は引数を介しgetClasses
て、クラスを探す環境を選択させてくれます。
以下は、例外を除いてどこにでもあるように見える.GlobalEnv
ため、私のクラスが見つかりません。それはいいです:
今、私.GlobalEnv
はクラスA
だけを調べて見つけました。それもいいです:
3) カスタム標準ルックアップ関数の作成
標準関数(これは必要な機能の最初の部分にすぎず、戻り値を正式な引数として渡すのではなく、そのメソッド内で計算したい) にルックアップ ビアを配置するgetClasses
と、すべて正常に動作します。getClasses()
4) 正式な S4 メソッドの作成
ただし、すべてを正式なS4メソッドgetClasses()
に入れると、クラスを探すために使用する標準環境に関していくつかの変更があるようです
以前"A" %in% foo1(where=NULL)
はFALSE
(望ましい)でした"A" %in% foo2(where=NULL)
が、TRUE
現在は ( 望ましくない) です。
foo2()
とまったく同じように動作する方法はありfoo1()
ますか?
編集 2012-08-29
Josh O'Brien が以下のコメントで指摘したように、変動はおそらく遅延評価によって引き起こされます。
デバッグfoo1()
デバッグ トレーサーに入ります。<RETURN>
4回ヒットした後、次のように入力しますget("where")
。
<RETURN>
コンソールで、 1 回ヒットしてから次のように入力しますevList
。
入力Q
して現在のデバッグ実行を終了します
すべてをもう一度実行しますが、デバッグ呼び出しがわずかに異なります
コンソールで、<RETURN>
5 回ヒットしてから次のように入力しますevList
。
次のように入力しますget("where")
。
今where
指しているnamespace:methods
`foo2()' のデバッグ
デバッグ トレーサーに入ります。<RETURN>
4回ヒットした後、次のように入力しますget("where")
。
次に、<RETURN>
1回押してから次のように入力しますevList
。
入力Q
して現在のデバッグ実行を終了します
すべてをもう一度実行しますが、デバッグ呼び出しがわずかに異なります
<RETURN>
5回ヒットした後、次のように入力しますevList
。
次のように入力しますget("where")
。
前に実行したデバッグevList
と比較して、と の値が異なることに注意してください。where
と入力Q
して、現在のデバッグ実行を終了します。
これは私にはやや奇妙に思えますが、おそらく言語設計者の観点からは理にかなっています。where
に関連付けられた環境を指すように明示的に設定する方法がわかれば、おそらく大丈夫でしょうnamespace:methods
。