2013-08-29 13 views
12

私は、機能がforecast.myclassであるパッケージを開発中です。その機能をforecastパッケージでうまく動作させたい。私。 forecastパッケージがロードされると、コードforecast(object)は私のパッケージからforecast.myclassに電話する必要があります。パッケージをロードせずに別のパッケージからS3メソッドを拡張する方法

私はパッケージforecastからforecastの唯一の一般的な定義を必要とする、と私は私が依存に含めるには消極的だパッケージforecastから、他の機能を使用していないので。だから私は、次のように私のパッケージに一般的な定義:パッケージforecastがロードされていない場合に予想されるように

##' 
##' @export 
forecast <- function(object,...) UseMethod("forecast") 

##' @rdname forecast.midas_r 
##' @method forecast midas_r 
##' @export 
forecast.midas_r <- function(object,newdata=NULL,method=c("static","dynamic"),insample=get_estimation_sample(object),...) { 

今、すべての作品。しかし、パッケージforecastをロードすると、を実行するときにforecast.midas_rが呼び出されません。ここで、objectはクラスmidas_rです。この問題をどのように解決すればよいですか?

+1

あなたが 'forecast.midas_r'を文書化しているのでなければ、' @ S3method(forcast、midas_r) 'だけが必要です - それはRdファイルを作成しませんが、NAMESPACEに正しい行を追加します – hadley

+0

@hadley forecast.midas_rは、forecast.midas_rが同じヘルプページを共有する方法で記述します。コードはここにあります:https://github.com/mpiktas/midasr/blob/master/R/midas_r_methods.R、行279から始まります – mpiktas

答えて

4

ここでの問題は、forecastジェネリックの定義が予測パッケージから定義をマスクしており、そのメソッドが予測パッケージジェネリックではなくジェネリックに関連付けられていることです。これは、同じ名前の関数を定義する2つのパッケージの複雑なインスタンスです。ソリューションは、予測に基づいているか、またはコマンドラインで、パッケージと予測の両方が完全に添付されている場合はmypackage::forecast()、またはインポート:予測は予測するが、 require(forecast)(これは、forecastの機能がパッケージに何らかの形で含まれていた場合、たとえば2Dでのプロットが十分な3Dでのプロットの場合などに適しています)。

インポートしたS4 genericをPkgAから定義してエクスポートしたS4メソッドは、S4 genericを暗黙的にユーザーに公開するため、Imports:PkgAがDESCRIPTIONファイルに指定されていても使用できます。 PkgB。

3

考えられる解決策の1つは、forecast.midas_rを強制的にエクスポートすることです。これは、の後に毎回NAMESPACEexport(forecast.midas_r)に手動で更新することを意味します。

これは、パッケージに、forecast.midas_rが表示されます。 forecast.midas_rがエクスポートされておらず、パッケージのネームスペースにのみ存在する場合は、パッケージとロードされている場合、という一般的なパッケージは、パッケージと同じ機能で上書きされます。したがって、forecastが不明なオブジェクトに対して呼び出されると、Rはパッケージの予測の一般的な作業領域内の対応するメソッドを検索します。 forecast.midas_rはプライベートメソッドなので、Rはそれを見つけず、エラーを生成します。

NAMESPACEを手動で更新する必要があるため、これは完璧な解決策ではありませんが、解決策です。

7

これには簡単な解決策はありません。他の人が言っているように、一般的な方法を再定義するのではなく、Dependsを使用してこの問題を回避するのが最も簡単です。

ここに私のために働く簡単な例があります。これはおおむねあなたのソリューションと同じですが、@exportと指定すると、NAMESPACEファイルを手動で更新する必要はありません。

##' @name mean 
##' @export mean.newClass 
##' 
##' @method mean newClass 
##' 
##' @title mean for \code{newClass} object 
##' @param x A \code{newClass} object 
##' @param ... Additional arguments 
##' 
mean.newClass <- function(x, ...){ 
    stopifnot(class(x)=="newClass") 
    return(42) 
} 

package.skeleton("newPkg")。ファイルmean.Rを上記の内容でパッケージの/Rディレクトリに置きます。

私はmeanbase内の関数ですが、私は他の場所での一般的な機能を変更するためにこれをテストして実現する今

roxygenize("newPkg", roxygen.dir="newPkg", copy.package=F, unlink.target=F) 

そして、あなたは以下のディレクトリ1レベルにいる

library(devtools) 
dev_mode(on=TRUE) ### don't want to have to uninstall the package later 
install_local("newPkg") 
library(newPkg) 
x <- c(1,2) 
class(x) <- "newClass" 
stopifnot(mean(x)==42) 
stopifnot(mean(unclass(x))==1.5) 

を確認してください彼らに新しい方法を与えてください、それはあなたのより一般的な場合にも拡張するべきです。

関連する問題