4

これは、StackOverflow に関する私の最初の質問投稿です。プロトコル エラーがあれば修正してください。しかし、私はサイトの他の多くの質問への回答からすでに大きな恩恵を受けているので、先に進む前に、サイトに貢献しているコミュニティに感謝したいと思います.

概要

R、RStudio、およびパッケージdevtoolsroxygen2Windows 7マシンで使用しています(session_info質問の最後に完全に記載されています)

SpatialLinespackageから S4 クラスのサブクラスを定義し、 packagespも使用する独自のパッケージを作成しようとしていますrgeosdocument私の問題は、 load_all自分のパッケージに devtools を使用したときに、よくわからず、完全に解決できない警告メッセージに関連しています。

警告メッセージ

最初のメッセージは

class "Spatial" is defined (with package slot ‘sp’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL’ 

これを解決すると、NAMESPACE ファイルにエントリを追加して (なぜそれが必要なのかを完全には理解せずに)、DESCRIPTION ファイルにさらに変更を加えると、2 番目のメッセージが表示されます。

d> devtools::document()
Updating minweSpatialNULL documentation
Loading minweSpatialNULL
Error: class "SpatialLinesNULL" is not exported by 'namespace:rgeos'

私が試したこと、および私が残した質問

ヒントを求めていくつかのサイトをグーグルで検索しましたが、最も近いものは、SpatialLinesNULL がどこから来たのかを尋ねる 2011 年 12 月の短いスレッドでしたrgeoshttp://lists.r-forge.r-project.org/pipermail/rspatial-devel/2011-December/000033.html

私は自分で何が悪いのかを理解するために実験を試み、何が起こっているのかを理解するのに十分なほど深く理解することができなかったので、道に迷うまでデバッガーでコードをステップ実行しました。その過程で、問題の小さな (そうではない) 実例が生成されました。これを以下に示します。

3 つの質問があります。それらはここに要約されていますが、実際には、以下の(実際には動作していない)おもちゃの例のコンテキストでのみ意味があります。

  • 質問 1Spatial (test1 の後)とにかくR が (仮想?) スーパークラスを必要とするのはなぜですか MyClass2
    明確化の追加@importClassesFromR のパッケージ化名前空間メカニズムは、実際に使用するクラスを編集した後、前件/スーパークラスを見つけてアクセスする必要があると考えていました。
  • 質問 2 (test3 の後) 最初の警告メッセージの理由が何であれ、この同様のメッセージの理由でもあると思います。
    私は正しい軌道に乗っていますか?
  • 質問 3 (test4 の後) test3 からの警告とそれに続くこのエラーは、自分で解決できるものですか? rgeosそれとも、パッケージの管理者に助けを求める必要がありますか(例: export を依頼するなどSpatialLinesNULL)?

コード例

私のおもちゃの作業例のrコード(スペースを節約するためにroxygenコメントのみを取り除いたもの)は次のとおりです。

MyClass1 <- setClass('MyClass1', contains = c('SpatialLines'))
MyClass2 <- setClass('MyClass2', contains = c('MyClass1'))

MyClass2 の第 2 世代のサブクラスは重要なようです (それがなければ警告は消えます)。私はなぜなのか理解していない。

devtoolsと を使用し て、このコードで一連のテストを実行しましたroxygen2。テストは、NAMESPACE ファイルの内容と、DESCRIPTION ファイルの Imports ディレクティブの内容によって異なります。テストの実行は、RStudio での実行devtools::load_all()(または途中devtools::document()での呼び出し) で構成されます。load_all()発生する警告メッセージは上記に掲載されています。各テストの間にクリーンなグローバル環境で R セッションを再起動します (警告は、load_allまたはを最初に実行したときにのみ発生しますdocument)。

以下の回答をフォローアップしているときに、シェルコマンドラインからRを使用しておもちゃのパッケージをビルドおよびインストールする必要があることに気付きました。

テスト1

test1 には DESCRIPTION ファイルのエントリがあります (完全な DESCRIPTION ファイルについては、この質問の最後を参照してください)。

Imports:
    methods,
    sp

完全な NAMESPACE ファイル (上で省略した roxygen コメントから生成) は次のとおりです。

# Generated by roxygen2 (4.1.0.9001): do not edit by hand

importClassesFrom(sp,SpatialLines)
importFrom(sp,SpatialLines)

再起動した R セッションで実行devtools::load_all()(またはdevtools::document()) しようとすると、最初の警告が生成されます (上記を参照)。

質問 1 R が ~~(virtual?)~~ スーパークラスを必要とするのはなぜですか?コードで Spatial第 2 世代が定義されている場合にのみ、なぜですか? 明確化の追加R のパッケージ化名前空間メカニズムは、実際に使用するクラスを編集した後、前件/スーパークラスを見つけてアクセスする必要があると考えていました。MyClass2@importClassesFrom

テスト2

test2は、警告メッセージが示すように NAMESPACE ファイルを更新することで問題を解決します。他の変更は行われませんでした。

完全な NAMESPACE ファイルが次の場合、警告は消えます。

# Generated by roxygen2 (4.1.0.9001): do not edit by hand

importClassesFrom(sp,Spatial)
importClassesFrom(sp,SpatialLines)
importFrom(sp,SpatialLines)

テスト3

ただし、DESCRIPTION ファイルの Imports ディレクティブに 1 つの小さな変更を加えると、明らかに同様の問題が再発しますrgeos。これは、test2 から test3 シナリオを作成するために行われた唯一の変更です。

Imports:
    methods,
    sp,
    rgeos

これで、test1 の問題のような警告が表示されます。つまり、次のようになります。

class "SpatialLinesNULL" is defined (with package slot ‘rgeos’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL

私が知る限り、SpatialLinesNULLは の新しいスーパークラスでありSpatial、 で定義されrgeosているため、いくつかの汎用関数とメソッドを提供できます。

質問 2最初の警告メッセージの理由が何であれ、それがこの同様のメッセージの理由でもあると思います。
私は正しい軌道に乗っていますか?

テスト4

test4では、test2 で行ったのと同じ解決策を適用しようとしています。つまり、欠落しているエントリを NAMESPACE ファイルに追加します。これは、test4 の完全な NAMESPACE ファイルです。

# Generated by roxygen2 (4.1.0.9001): do not edit by hand

importClassesFrom(rgeos,SpatialLinesNULL)
importClassesFrom(sp,Spatial)
importClassesFrom(sp,SpatialLines)
importFrom(sp,SpatialLines)

どの段階で、最終的なエラーメッセージが表示されます:

d> devtools::document()
Updating minweSpatialNULL documentation
Loading minweSpatialNULL
Error: class "SpatialLinesNULL" is not exported by 'namespace:rgeos

この段階で私は立ち往生しています。

質問 3 test3 からの警告とそれに続くこのエラーは、自分で解決できるものですか? rgeosそれとも、パッケージの管理者に助けを求める必要がありますか(例: export を依頼するなどSpatialLinesNULL)?

session_info (test4 から)

d> devtools::session_info()
Session info --------------------------------------------------------------------------
 setting  value                       
 version  R version 3.1.2 (2014-10-31)
 system   x86_64, mingw32             
 ui       RStudio (0.98.953)          
 language (EN)                        
 collate  English_Australia.1252      
 tz       Australia/Sydney            

Packages ------------------------------------------------------------------------------
 package          * version    date       source        
 devtools         * 1.7.0.9000 2015-02-20 local         
 lattice          * 0.20-29    2014-04-04 CRAN (R 3.1.2)
 minweSpatialNULL * 0.0.0.9000 <NA>       local         
 Rcpp             * 0.11.4     2015-01-24 CRAN (R 3.1.2)
 rgeos            * 0.3-8      2014-09-21 CRAN (R 3.1.2)
 roxygen2         * 4.1.0.9001 2015-02-21 local         
 rstudio          * 0.98.953   2014-08-02 local         
 rstudioapi       * 0.2        2014-12-31 CRAN (R 3.1.2)
 sp               * 1.0-17     2015-01-08 CRAN (R 3.1.2)
 stringr          * 0.6.2      2012-12-06 CRAN (R 3.1.1)
d>

test4 の完全なファイル

R/myclasses.r

#------------------------------------------------------------------------------
#' MyClass1
#' 
#' A subclass of SpatialLines
#' 
#' MyClass1 is a subclass of sp::SpatialLines.
#' @importClassesFrom sp SpatialLines Spatial
#' @importFrom sp SpatialLines
#' @importClassesFrom rgeos SpatialLinesNULL
MyClass1 <- setClass('MyClass1', contains = c('SpatialLines'))

#------------------------------------------------------------------------------
#' MyClass2
#' 
#' A subclass of MyClass1
#' 
#' MyClass2 is a subclass of MyClass1 and a 2nd generation subclass of
#' sp::SpatialLines.
#' @importClassesFrom sp SpatialLines
MyClass2 <- setClass('MyClass2', contains = c('MyClass1'))

説明ファイル

Package: minweSpatialNULL
Title: Minimum Example of my Problem with SpatialLinesNULL
Version: 0.0.0.9000
Authors@R: person("Geoff", "Lee", , "geoff.lee@gmail.com", role = c("aut", "cre"))
Description: (Hopefully) demonstrates my problem with warnings
  that I cannot seem to eradicate. 
Depends: R (>= 3.1.2)
Imports:
    methods,
    sp,
    rgeos
License: GPL (>= 2.0)
LazyData: true

名前空間ファイル

# Generated by roxygen2 (4.1.0.9001): do not edit by hand

importClassesFrom(rgeos,SpatialLinesNULL)
importClassesFrom(sp,Spatial)
importClassesFrom(sp,SpatialLines)
importFrom(sp,SpatialLines)

結論

提供できるヘルプ、アドバイス、またはガイダンスを事前に感謝します。たとえそれが私がより良い質問をする方法についてであっても:-)

4

2 に答える 2

3

この回答は、同様の問題に遭遇した他の人の利益のために、私が尋ねた一連の質問に関連して私が学んだすべての情報をまとめたものです。

質問された順序とは逆の順序で回答を提示する方が簡単であることが判明しました。

私の特定の問題を実際に解決した側面は、@ Edzer Pebesma によって提供されました-感謝しています。

John Chambers は、私が r-devel メーリング リストで尋ねた、より具体的な追加の質問に答えてくれました。これは、警告メッセージが表示された理由についての理解のギャップを埋めるのに本当に役立ちました。彼の指導と支援にも非常に感謝しています。

以下の説明に残っている誤りは、すべて私自身のものです!

この質問と回答で参照されているおもちゃのパッケージの test4 バージョンは、 --> http://github.com/Geoff99/Examples/tree/SpatialLinesNULLの github リポジトリのブランチ SpatialLinesNULL のフォルダー SpatialLinesNULL <-- その他にあります。テスト シーケンスのバージョンは、NAMESPACE ファイルと DESCRIPTION ファイルから 1 ~ 2 行を削除することで作成できます。

2017 年 5 月 6 日の更新 - test4 バージョン コードがhttps://gist.github.com/Geoff99/29be25bce4cd4c918921bf68769c6a39の Gist に移動しました

質問 3 (test4 後)

test3 からの警告とこの後続のエラーは、自分で解決できるものですか? または、rgeos パッケージの管理者に助けを求める必要がありますか (たとえば、SpatialLinesNULL をエクスポートするように依頼します)?

test3 からの警告は

class "SpatialLinesNULL" is defined (with package slot ‘rgeos’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL

そしてtest4からのエラーメッセージは

d> devtools::document()
Updating minweSpatialNULL documentation
Loading minweSpatialNULL
Error: class "SpatialLinesNULL" is not exported by 'namespace:rgeos

これに対する最善の解決策は、パッケージのメンテナーに連絡して、警告およびエラー メッセージに記載されているrgeos不足しているクラスをエクスポートするように依頼することでした。SpatialLinesNULLEdzer Pebesma がこれに答えてくれて、rgeosパッケージに必要な更新も加えてくれて、とても感謝しています。アップグレードされたバージョンのパッケージをインストールした後、おもちゃのパッケージの NAMESPACE ファイルにrgeos追加するだけで、警告は消えました。importClassesFrom(rgeos,SpatialLinesNULL)

別のパッケージで同様の状況に直面している場合は、それが推奨される戦略です。

これを自分で解決SpatialLinesNULL classできる方法があると思います (基本的には、パッケージの名前空間環境で欠落しているメタデータのコピーを手動で作成することで、これは基本的methodsに、警告を発行した後にパッケージ自体が行うことです) -- -しかし、それは非常に厄介なハックであるため、その方法の説明は控えます. 将来のある段階で本当にこれを行う必要がある場合は、質問 1 (下記) への回答で、ハッキングの方法を理解するために必要な情報を収集できます。

質問 2 (test3 後)

最初の警告メッセージの理由が何であれ、この同様のメッセージの理由でもあると思います。私は正しい軌道に乗っていますか?

test3 からの警告は

class "SpatialLinesNULL" is defined (with package slot ‘rgeos’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL

そして、test1 からの最初の警告は

class "Spatial" is defined (with package slot ‘sp’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL’ 

答えはyesでした。両方のメッセージが同じ理由で表示されます。

警告メッセージは両方とも.findOrCopyClass、メソッド パッケージ内の内部 (つまり、エクスポートされていない) 関数で呼び出される関数によって生成されます。この関数のコードを表示するには、:::演算子を使用する必要があります。methods:::.findOrCopyClassR コンソールに入力します。(これにはメソッドパッケージをロードする必要があり、ほとんどの場合そうです)。クラスを定義するメタデータ.findOrCopyClassが見つからず、メタデータをコピーする必要がある場合、この警告が発行されます。

メタデータとは何か、おもちゃのパッケージの名前空間にメタデータを含める必要がある理由、および (私の推測では) この警告が発行される理由については、以下を参照してください。

.findOrCopyClassこれはsetIsmethodsパッケージからエクスポートされた関数です。次にsetIs、メソッド function によって (数回)setClass呼び出されます。これは、おもちゃのパッケージの例で呼び出します。これらの機能の詳細については?setIs、 とを入力してください。?setClassまたは、ソース コードを見たい場合は、R コンソールにsetIsorと入力してください。setClass

質問 1 (test1 の後)

なぜ R は ~~(virtual?)~~ スーパークラス Spatial を必要とするのですか?

@importClassesFrom明確化の追加: R パッケージ化名前空間メカニズムは、実際に使用するクラスを編集した後、前件/スーパークラスを見つけてアクセスする必要があると考えていました。

まずはお詫びと訂正。

  • 尋ねた元の質問の部分:

    コードで第 2 世代の MyClass2 が定​​義されている場合にのみ、なぜですか?

    単純に間違っていました。質問を投稿する前に確認したにもかかわらず、無意識のうちに隠し情報がキャッシュされていたに違いありませんglobalenv()MyClass1おもちゃのパッケージでしか定義していない場合でも、根本的な問題が存在します。

  • Spatial仮想クラスではありません。仮想クラスですSpatialLinesNULL スーパークラスが仮想かどうかは、この問題とは関係ありません。

  • この問題は多くのことと関係があります
    • スーパークラスが定義されている場所 (私のおもちゃの例では、Spatialcomes fromspSpatialLinesNULLcomes from rgeos)
    • スーパークラス定義がそのパッケージからエクスポートされるかどうか (おもちゃの例では、spおよびrgeos)
    • したがって、R がスーパークラス (例: ) を含むクラス(例: )minweSpatialNuULLを使用する新しいパッケージ (例:SpatialLinesSpatialSpatialLinesNULL

不足しているメタデータの警告メッセージについて

methods以下は、パッケージのドキュメントの注釈付きウォークスルーです。理解するのに少し時間がかかりましたが、それは私が始めたときの知識ベースが低かったためです. ドキュメンテーションは非常に役に立ちます。ここまで理解したら、一読することをお勧めします。?setClass?Classes?getClassDef?classMetaNameおよび ?setIs特に価値のあるエントリが見つかりました。

setClass

ドキュメントから?setClass(私が強調して追加):

表現 (スロット) および/またはこの表現に含まれるクラス (スーパークラス)、およびその他のオプションの詳細を指定して、クラス定義を作成します。副作用として、クラス定義は指定された環境に格納されます。ジェネレーター関数は setClass() の値として返され、クラスが仮想でない場合にクラスからオブジェクトを作成するのに適しています。

によって発行される警告メッセージmethods:::.findOrCopyClassは、クラス定義の作成と保存に関連しています。クラス定義はメタデータ オブジェクトです (または格納されますか?)。

メタデータ オブジェクト とは

?Classesドキュメントから:

クラス定義は、R オブジェクトのクラスの正式な定義を含むオブジェクトです。

クラスが定義されると、そのクラスに関する情報を含むオブジェクトが格納されます。class を定義するメタデータと呼ばれるオブジェクトは、クラスの名前 (プログラマーがその名前の生成関数を記述できるようにするため) ではなく、特別に作成された名前で格納されます。クラス定義を調べるには、 を呼び出しますgetClassメタデータ オブジェクトの情報には次のものが含まれます。

  • スロット...
  • スーパークラス...
    • クラスと特定のスーパークラスの間の関係に関する情報は、クラス SClassExtension のオブジェクトとしてエンコードされます。スーパークラス (場合によってはサブクラス) のそのようなオブジェクトのリストは、クラスを定義するメタデータ オブジェクトに含まれています。
  • プロトタイプ...

このmethodsパッケージは、これらのメタデータ オブジェクトを作成および管理するためのものです (S4 クラス用、および可能な限り古い S3 クラス用)。

新しいクラス ( など) のメタデータ オブジェクトにはMyClass1、その定義内のすべてのスロットに関する情報が含まれます ( package で定義され たクラスからすべてのスロットを継承するようにMyClass1指定されているため)。 contains = c('SpatialLines')SpatialLinessp

重要なことは、クラスのメタデータ オブジェクトにはスーパークラスに関する情報も含まれている必要があるということです。そして、何らかの方法で、スーパークラスに関する情報が継承ツリーのずっと上に到達する必要があります。この例でMyClass1は、 は 1 つのスーパークラス に距離を置いているSpatialLinesため、 のより遠い祖先がSpatialLines誰であれ、すべて継承します。

  • 私はどこかで読んだと思いますが、メタデータ オブジェクトが 2 つの状態 (不完全または完全) になる可能性があることをリンクを間違えました。不完全な状態では、新しいクラス (例: MyClass1) のスーパークラスのリストは、(まだ) 継承チェーンのずっと上まで埋められていない可能性がありますが、クラス定義が使用されるまでに、R は継承をトラバースする必要があります。連鎖し、クラスの完全な系図を記入します。パッケージをチェックまたはインストールするときは、継承チェーンが完了している必要があります。まだ完了していない場合は、install.packagesステップ中に完了している必要があります。
メタデータ オブジェクトの見方

getClassまたはgetClassDefを使用して、特定のクラスのメタデータ オブジェクトを表示します。

ドキュメント?getClassまたは?getClassDefR がメタデータ オブジェクトを検索する環境について説明しています。注意すべき重要な点は、パッケージで定義されたクラスのメタデータ オブジェクトを見つける前に、少なくともパッケージをロードする必要があるということです。

これは、クラスをエクスポートする のminweSpatialNULLバージョン 0.3-9 をロードした後の私のおもちゃパッケージ ( ) の例です。次の点に注意してください。rgeosSpatialLinesNULL

  • MyClass1すべての親スーパークラスを知っている (通常の状況)、および
  • SpatialLinesNULL(パッケージで定義されたClass Unionです) は、 orについて何も知らないにもかかわらず、ほとんどすべての子サブクラスを知っています。rgeosrgeosMyClass1MyClass2

    d> getClass('MyClass1')
    Class "MyClass1" [package "minweSpatialNULL"]
    
    Slots:
    
    Name:        lines        bbox proj4string
    Class:        list      matrix         CRS
    
    Extends: 
    Class "SpatialLines", directly
    Class "Spatial", by class "SpatialLines", distance 2
    Class "SpatialLinesNULL", by class "SpatialLines", distance 2
    
    Known Subclasses: "MyClass2"
    
    
    d> getClass('SpatialLinesNULL')
    Extended class definition ( "ClassUnionRepresentation" )
    Virtual Class "SpatialLinesNULL" [package "rgeos"]
    
    No Slots, prototype of class "NULL"
    
    Known Subclasses: 
    Class "NULL", directly
    Class "SpatialLines", directly
    Class ".NULL", by class "NULL", distance 2, with explicit coerce
    Class "SpatialLinesDataFrame", by class "SpatialLines", distance 2
    Class "MyClass2", by class "MyClass1", distance 3
    d> 
    
  • 実際には のサブクラスであることをSpatialLinesNULL知っているのは少し気になりますが、それ自体について直接言及していないようです理由はまだわかりません。MyClass2MyClass1MyClass1

スーパークラスのリストが変更される理由

おもちゃのパッケージの DESCRIPTION ファイルのディレクティブに追加するMyClass1以外はパッケージに変更を加えなかったのに、おもちゃのクラスのスーパークラスのリストが変更された理由について、しばらく戸惑いました。rgeosImports

その理由は、メソッド パッケージが非常に巧妙だからです。サブクラスを定義するだけでなく、クラスが定義された後、親スーパークラスをクラスのファミリー ツリー (継承チェーン) に挿入することができます。

簡単な方法は(説明のためのsetClassUnionタイプ) を使用することです。?setClassUnionそれがrgeos定義時に行うことですSpatialLinesNULL- の新しい親を作成しSpatialLinesます。rgeosそのため、おもちゃのパッケージの DESCRIPTION ファイルにエントリを追加するとすぐに、クラスMyClass1は突然別のスーパークラスも取得しました。rgeosインタラクティブな設定では、パッケージをロードした (またはアタッチしてロードした) かどうかに応じて、おそらく同様のことが起こったでしょう。

から祖先を追加するもっと複雑な方法もあります - を参照してください?setIs

メタデータ オブジェクトの名前

他のすべてのオブジェクトと同様に、R はメタデータ オブジェクトをその名前で検索します。オブジェクトがパッケージで定義されている場合、オブジェクトの名前は

  • パッケージの名前空間環境 (例: environment: namespace:minweSpatialNULL)、または
  • パッケージのインポート環境 (例: environment: imports:minweSpatialNULL)。

?Classes再びドキュメントから:

クラスが定義されると、そのクラスに関する情報を含むオブジェクトが格納されます。クラスを定義するメタデータと呼ばれるオブジェクトは、クラスの名前(プログラマがその名前の生成関数を記述できるようにするため) ではなく、特別に作成された名前で格納されます。

classMetaNameメソッド パッケージが提供する関数を使用して、特別に構築された名前を見つけることができます。詳細については、 を参照?methods::classMetaNameしてください。

私のおもちゃのパッケージから取られたメタデータ オブジェクトの名前の例は次のとおりです。

d> classMetaName('MyClass1')
[1] ".__C__MyClass1"

.このメタデータ オブジェクトの名前 (つまり) は先頭に付いているため、.__C__MyClass1通常ls、パッケージの名前空間環境では非表示になりますが、 へのall.names = TRUE引数を使用して表示できますls

d> # Recall that MyClass1 is the name I chose for the generator function 
d> #  returned by setClass when I defined the class MyClass1
d> env_toy_package <- environment(MyClass1)
d> ls(env_toy_package, all.names=TRUE)
[1] ".__C__MyClass1"       ".__C__MyClass2"       ".__DEVTOOLS__"       
[4] ".__NAMESPACE__."      ".__S3MethodsTable__." ".packageName"        
[7] "MyClass1"             "MyClass2"            
d> 

parent.envパッケージの名前空間環境 (つまり、名前空間環境) を調べるimports:minweSpatialNULLと、 のスーパークラスの隠し名前が見つかりますMyClass1。これは、.findOrCopyClassそこに配置できるように探していたものです!

d> parent.env(env_toy_package)
<environment: 0x0000000008df59d8>
attr(,"name")
[1] "imports:minweSpatialNULL"

d> ls(parent.env(env_toy_package), all.names = TRUE)
[1] ".__C__Spatial"          ".__C__SpatialLines"     ".__C__SpatialLinesNULL"
[4] "library.dynam.unload"   "SpatialLines"           "system.file"           
d> 
最後に、「.findOrCopyClass」警告の内容

.findOrCopyClass次のような警告を出す場合:

class "Spatial" is defined (with package slot ‘sp’) but no metadata object found to revise subclass information---not exported?  Making a copy in package ‘minweSpatialNULL’ 

この関数は、検索した名前空間で非表示の名前を見つけることができなかったことを知らせており、その名前がバインドされているオブジェクトのメタデータを修正しています。クラス自体のメタデータ オブジェクトがその親スーパークラス ( ) が存在する場所を示しているため.__C__Spatial、非表示の名前がどこにあるべきかを認識しています。メタデータ オブジェクト内の先祖スーパークラスの完全な仕様には、先祖スーパークラスが定義されたパッケージの名前を含む属性が含まれます。これは、2 つの既存のロード済みパッケージがクラスに同じ名前を選択した場合に備えてです!spSpatialLinesSpatialpackage

そのためimportClassesFrom、不足しているスーパークラスを ing すると機能します。これにより、不足している非表示の名前がおもちゃパッケージのimports:minweSpatialNULL環境に取り込まれ、そこからそれらを見つけて、必要に応じて更新することができます。minweSpatialNULL.findOrCopyClass

.findOrCopy警告を発する 理由

.findOrCopyClassメタデータ オブジェクトが見つからないと言ったのはなぜだろうと思ったのですが、次に言ったのは、パッケージの名前空間でコピーを作成しているということでした! 私はその質問を r-devel メーリング リストに投稿し、John Chambers が親切に答えてくれました (強調は私が追加しました)。

クラス定義を見つける目的は、警告メッセージが示すように、新しい関係のエントリを更新することです。これには、定義を保持する名前空間が書き込み可能である必要があります。

サブクラス情報の場合、現在ロードされているパッケージでない場合、元の名前空間はロックされている可能性が非常に高くなります。サブクラス情報を更新するために定義をコピーすることが唯一の合理的な選択のようであり、警告メッセージは必要ありません。

改訂版では、このメッセージが省略されます。

オブジェクト (関数やクラス (正確には、関数オブジェクトやクラス メタデータ オブジェクト) など)の名前に何が起こるか、オブジェクト自体に何が起こるかの違いに関連する私の残りの概念的な問題。または、言い換えれば、名前空間 (おそらくロックされている) を更新する必要があるかどうか、またはオブジェクト (の状態) 自体を更新する必要があるかどうかです。

'findorCopyClassesは、(エクスポートされていない) スーパークラスが見つからないと文句を言っているのではなく、スーパークラスの値を変更できる場所で見つけられないということです。

ロックとは

?base::bindenvドキュメントには次のように書かれています:

「名前空間を持つパッケージの名前空間環境は、ロード時にロックされます。」

ロックされた環境とは、

" 環境からの変数バインディングの追加または削除を防ぎます。バインディングがロックされていない限り、変数の値を変更することは引き続き可能です"

しかし、少し実験してみると、パッケージの名前空間環境がロックされているだけでなく、imports:namespaceのバインディングもロックされていることがわかり ました。ロックされたバインディングとは、次のことを意味します。

「ロックされたバインディングの値は変更できません」。

したがって、スーパークラス メタデータ オブジェクトは別のパッケージ (例: rgeos) から取得されるため、その別のパッケージの名前空間でのバインディングはロックされ、その値は変更できません。または、例に関して言えば、メソッドパッケージが「所有する」サブクラスのリストに追加したい場合、のバインディングMyclass1または正確には、隠し名前のバインディング)がロックされているため、追加できないことがわかります。したがって、コピーを作成する必要があるというメッセージです。MyClass2SpatialLinesNULLSpatialLinesNULL.__C__SpatialLinesNULL

コピーの代わりに、他のパッケージの名前空間でバインディングを一時的にロック解除し、オブジェクトを更新して、バインディングを再度ロックすることもできますが、環境とバインディングのロックについて学んだばかりなので、その結果がどうなるかわかりませんなれ。私は一人で十分に去ります。

OK、必要なスーパークラスがエクスポートされていない場合のソリューション をハックする方法

警告私はこれほど多くのことをテストしておらず、とにかく悪い考えですが、もしあなたが本当に警告メッセージを消し去りたいと切望しているなら...

ステップ1。警告メッセージを見て、欠落しているスーパークラスの (テキスト) 名と、それが由来するパッケージを見つけます。

ステップ2。classMetaName不足しているエクスポートされていないスーパークラスの隠されたマングルされた名前を見つけるために使用します。スーパークラスのMissingSuperclass場合、おそらく.__C__MissingSuperclass

Step3. 独自のクラスを作成するために呼び出す前に、:::アプローチを使用してメタデータ オブジェクト (つまり ) にアクセスし、パッケージに属する適切な環境でdonorpackage:::.__C__MissingSuperclass適切な名前 (つまり) を付けます。.__C__MissingSuperclasssetClass

すでに述べたように、これは本当に悪い考えです。なぜなら、自分の足を撃つことは非常に簡単だからです。また、警告メッセージが送信された後にそれが本質的に行われているように見えるため、とにかく気.findOrCopyClassにする必要はありません。setIs

終わり

ここまで読んでくださった方、少しでもお役に立てれば幸いです!私は、主に将来の私のためのチュートリアルとして、そのような長さでそれを書きました:-)

于 2015-03-12T12:46:56.700 に答える
2

この広範な質問をありがとう。それを改善するために2つの提案があります。まず、再現可能な例を提供してください。この場合、警告またはエラー メッセージを再現できる最小限のパッケージになります。例えば、

MyClass1 <- setClass('MyClass1', contains = c('SpatialLines'))
MyClass2 <- setClass('MyClass2', contains = c('MyClass1'))

ロードされたセッションではsp問題なく動作しますが、パッケージ コードでこれを実行すると問題が発生します。このようなパッケージを作成することは、多くの推測作業を行うことを意味します: 完全なNAMESPACE. 2 番目: 問題を使用によって引き起こされた問題から分離しますdevtools(つまり、パッケージのビルドとインストールに関する標準の R パッケージ開発用語を使用します)。

あなたが提供するものから、私は答えることができます:

  • Q1:Spatialは仮想クラスではなく、すべての派生クラスに共通するもの (CRS とバウンディング ボックス) を定義するため存在し、すべての派生クラスで動作するメソッドが定義されているため必要です。MyClass2それが必要なのは、私が持っていないあなたのパッケージに関連しています
  • Q2: Q1 につながった警告が表示されていないため、お答えできません。また、SpatialLinesNULLは のスーパークラスではSpatialなく、SpatialLinesで定義される

    setClassUnion("SpatialLinesNULL", c("SpatialLines", "NULL"))

  • rgeosQ3:このクラスをエクスポートする修正版をコンパイルしてみてください。適切な使用例 (問題を再現する最小限のパッケージ) を提供すると、開発者の 1 人がrgeosそれを調べます。

于 2015-03-05T18:00:38.513 に答える