4

私は現在、生成に時間がかかる大きなオブジェクトのリファレンス クラス (R5) を開発しています。setRefClass でクラスを再定義し、メソッドを更新するたびにオブジェクトを再現するよりも、メソッドを開発するためのより良い方法を誰かが知っているのではないでしょうか。

つまり、既存の Reference クラス オブジェクトのメソッドを再定義できますか。

4

2 に答える 2

2

私は次のことを考えていました:

test <- setRefClass("TEST",
              fields = list(a = "numeric"),
              methods = list(
                        funA = function(){
                                      a <<- a+1
                                     },
                        initialize = function(){
                                          a <<- 1
                                          callSuper()
                                         }
                        )
)

ex1 <- test$new()

ex1$funA()

test$methods(funA = function(){
                      a <<- a+10
                     }
            )

ex$funA
# Class method definition for method funA()
# function () 
# {
#     a <<- a + 1
# }
# <environment: 0x0537f8ac>

ex1 <- test$new()$import(ex1)

ex$funA
# Class method definition for method funA()
# function () 
# {
#     a <<- a + 10
# }
# <environment: 0x04badc5c>

を使用してクラスの以前のメソッドを上書きできると思いますclass$methods(。その後、再定義されたクラスから新しいオブジェクトを設定し、古いオブジェクトをインポートできます。私は注意します:

「クラスのすべてのメソッドは、通常、パッケージの一部として、クラスを定義するソース コードで定義する必要があります。特に、名前空間を持つ添付パッケージ内のクラスでメソッドを再定義することはできません。クラス メソッドは、クラス定義のバインディングがロックされています。」から?setRefClassも。

于 2012-09-29T04:26:38.170 に答える
2

この問題は何ヶ月も私を悩ませました。今日、 https://stat.ethz.ch/pipermail/r-help/2012-January/299743.htmlに触発された非常に便利なソリューションを見つけました。

誤った実装を持つ ReferenceClass から始めましょう。

MyClass <- setRefClass(
  "MyClass",
  fields = list(
    xy = "data.frame"
  ),
  methods = list(
    initialize = function( df ){
      if( !missing( df ) ){
        xy <<- df
      }
    },
    getSecondRow = function(){
      # A mistake happend here
      return( xy[1,] )
    }
  )
)

mc <- MyClass$new( data.frame( a = 1:10, b = rnorm(10) ) )
mc$getSecondRow()

  a         b
1 1 0.1349983

の実装getSecondRowは明らかに望ましい結果を提供しません。したがって、固定メソッドは実際には次のようになります

    getSecondRow = function(){
      return( xy[2,] )
    }

コンストラクターの明示的な実装のないクラス

クラスをロードしてオブジェクトをゼロから再生成する代わりに、デフォルトinitialize( ... )コンストラクターのコピー コンストラクター機能を使用して、既存のオブジェクトから新しいオブジェクトを構築する方法があります。クラスをデバッグしてリロードした後、既存のオブジェクトを実装とともに同じ変数にコピーできます。

# NOTRUN
mc <- MyClass$new( mc )

コンストラクターが上書きされたクラス。

ただし、ここで示したケースでは、標準コンストラクターは既に上書きされています。ただし、そのような場合はcallSuper( ... )、コンストラクターが次のようになるように、の機能を使用するだけです。

    initialize = function( df, ... ){
      callSuper( ... )
      if( !missing( df ) ){
        xy <<- df
      }
    }

最後に、固定オブジェクトは次のように派生します

mc <- MyClass$new( mc$xy, mc )
mc$getSecondRow()

  a         b
2 2 0.8452587
于 2013-05-15T15:34:59.943 に答える