4

这是我在 StackOverflow 上发布的第一个问题,因此请更正我犯的任何协议错误。但是我已经从对网站上许多其他问题的回答中受益匪浅,所以在我继续之前,我要感谢为该网站做出贡献的社区。

概述

我在 Windows 7 机器上使用 R、RStudio、包和包(devtools问题结尾处完整)roxygen2session_info

我正在尝试编写自己的包,它SpatialLines从包中定义了 S4 类的子类sp,并且还使用了包rgeosdocument当我使用 devtools和 load_all我的包时,我的问题与我不太了解且无法完全解决的警告消息有关。

警告信息

第一条消息是

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 文件进行进一步的更改,我收到了第二条消息,到目前为止我已经被打败了。

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

我所尝试的,以及我留下的问题

我已经用谷歌搜索并搜索了几个寻找提示的网站,但我找到的最接近的是 2011 年 12 月的一个简短线程,询问 SpatialLinesNULL 来自哪里 --- 答案是rgeoshttp://lists.r-forge.r-project.org/pipermail/rspatial-devel/2011-December/000033.html

我已经尝试自己尝试了解出了什么问题,并在调试器中逐步执行代码,直到我迷路为止,这比我能够很好地理解应该发生的事情要深入得多。在此过程中产生了一个小(非)问题的工作示例,如下所示。

我有 3 个问题。它们在此处进行了总结,但实际上仅在下面我的(非)工作玩具示例的上下文中才有意义:

  • 问题 1(在 test1 之后)为什么 R 仍然需要(虚拟?)超类Spatial,为什么只有在我的代码中定义了第二代 MyClass2时?
    澄清补充说@importClassesFrom,我曾认为,一旦我编辑了我实际使用的类,R 打包命名空间机制就会满足查找和访问前项/超类的任何需要。
  • 问题 2(在 test3 之后)我假设无论我的第一条警告消息的原因是什么,也是这个类似消息的原因。
    我在正确的轨道上吗?
  • 问题 3(在 test4 之后)来自 test3 的警告和随后的错误是我可以自己解决的吗(如果可以的话)?还是我需要向rgeos软件包的维护者寻求帮助(例如要求他们导出SpatialLinesNULL)?

代码示例

我的玩具工作示例的 r 代码(仅去除 roxygen 注释以节省空间)是:

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

MyClass2 第二代子类似乎很重要(没有它,警告就会消失)。我不懂为什么。

devtools我使用and 对此代码运行了一系列测试roxygen2。测试因 NAMESPACE 文件中的内容以及DESCRIPTION 文件中的 Imports 指令中的内容而异。执行测试包括在 RStudio 中运行devtools::load_all()(或沿途devtools::document()调用)。load_all()发生的警告消息已在上面发布。我在每次测试之间在干净的全局环境中重新启动我的 R 会话(警告仅在我第一次运行时出现load_alldocument)。

在跟进下面给出的答案时,我意识到我也应该尝试从 shell 命令行使用 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,为什么只有MyClass2在我的代码中定义了第二代时? 澄清补充说@importClassesFrom,我曾认为,一旦我编辑了我实际使用的类,R 打包命名空间机制就会满足查找和访问前项/超类的任何需要。

测试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 指令(即添加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软件包的维护者寻求帮助(例如要求他们导出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 <-- 其他可以通过从 NAMESPACE 和DESCRIPTION 文件中删除一两行来构建测试序列的版本。

2017 年 5 月 6 日更新 - test4 版本代码移至https://gist.github.com/Geoff99/29be25bce4cd4c918921bf68769c6a39的要点

问题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联系包的维护者并要求他们导出SpatialLinesNULL警告和错误消息中提到的缺失类。Edzer Pebesma 为我回答了这个问题,并对rgeos软件包进行了必要的更新,对此我非常感激。安装升级版包后,rgeos我可以简单地添加importClassesFrom(rgeos,SpatialLinesNULL)到我的玩具包的 NAMESPACE 文件中,警告就消失了。

如果您使用不同的软件包面临类似的情况,这就是我推荐的策略。

怀疑有一种方法我可以自己解决这个问题(基本上是通过手动复制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’ 

答案是肯定的,两条消息出现的原因相同。

警告消息都是由调用的函数生成的,该函数.findOrCopyClass是方法包中的内部(即非导出)函数。要查看此功能的代码,必须使用:::运算符。键入methods:::.findOrCopyClassR 控制台。(这需要加载方法包,几乎总是这样)。.findOrCopyClass当它找不到定义类的元数据时发出此警告,因此它必须复制元数据。

请参阅下面的元数据是什么,为什么它需要包含在我的玩具包的命名空间中,以及(我的最佳猜测)为什么会发出此警告。

.findOrCopyClass由 调用setIs,它是从methods包中导出的函数。依次setIs由方法 function 调用(多次)setClass,我在我的玩具包示例中调用了该方法。键入?setIs?setClass以获取有关这些功能的更多信息。或者,如果您想查看他们的源代码,只需在 R 控制台中输入setIs或。setClass

问题1(test1后)

为什么 R 还是需要 ~~(virtual?)~~ 超类 Spatial ~~,为什么只有在我的代码中定义了第二代 MyClass2 时~~?

@importClassesFrom澄清补充说:我曾认为,一旦我编辑了我实际使用的类,R 打包命名空间机制就会满足查找和访问前项/超类的任何需要。

首先道歉和更正。

  • 原始问题中提出的部分:

    为什么只有在我的代码中定义了第二代 MyClass2 时?

    完全错了。尽管我在发布问题之前进行了检查,但我一定在不知不觉中仍然有一些隐藏的信息缓存在我的globalenv(). 即使我只MyClass1在我的玩具包中定义了潜在的问题。

  • Spatial不是虚拟类。SpatialLinesNULL 一个虚拟类。超类是否是虚拟的与这个问题无关。

  • 这个问题确实有很大关系
    • 定义超类的位置(在我的玩具示例中,Spatial来自spSpatialLinesNULL来自rgeos
    • 超类定义是否从该包中导出(在玩具示例中,sprgeos
    • 因此,当 R 检查和安装一个新包(例如)时,它是否以及如何找到超类定义,该包minweSpatialNuULL使用一个类(例如SpatialLines),其父类包括超类(例如SpatialSpatialLinesNULL)。

缺少元数据警告消息是关于什么的

以下是methods包的部分文档的注释演练。我花了一段时间才掌握,但这与我开始时知识基础薄弱有关。该文档非常有用,如果您能做到这一点,我建议您阅读它。?setClass我发现来自、、、?Classes?getClassDef的条目?classMetaName特别 ?setIs有价值。

setClass做 什么

?setClass文档(重点由我添加):

创建一个类定义,指定表示(插槽)和/或包含在这个类(超类)中的类,以及其他可选细节。作为副作用,类定义存储在指定的环境中。生成器函数作为 setClass() 的值返回,如果该类不是虚拟的,则适用于从该类创建对象。

发出的警告信息methods:::.findOrCopyClass与类定义的创建和存储有关。类定义是(或存储在?)元数据对象。

什么是元 数据对象

?Classes文档中:

类定义是包含 R 对象类的正式定义的对象,...

定义一个类时,会存储一个包含该类信息的对象。该对象称为定义类的元数据,它不存储在类的名称下(以允许程序员编写该名称的生成函数),而是存储在一个特殊构造的名称下。要检查类定义,请调用getClass. 元数据对象中的信息包括

  • 插槽...
  • 超级班...
    • 关于类和特定超类之间关系的信息被编码为类 SClassExtension 的对象。超类(有时是子类)的此类对象列表包含在定义类的元数据对象中
  • 原型 ...

这个methods包是关于创建和管理这些元数据对象的(对于 S4 类,并且尽可能地为旧的 S3 类)。

新类的元数据对象(例如MyClass1)在其定义中包含有关任何插槽的信息(因为MyClass1指定contains = c('SpatialLines') 它从类中继承所有插槽SpatialLines,在 package 中定义sp)。

重要的是,一个类的元数据对象必须包含有关任何超类的信息——否则新类如何从其父类(即超类)继承任何东西?一种又一种方式,关于超类的信息必须一直到达继承树。在这个例子中,MyClass1有一个超类的距离SpatialLines,因此继承了所有更远的祖先SpatialLines,无论他们是谁。

  • 我想我在某处读到过,但放错了链接,元数据对象可以处于两种状态 - 不完整或完整。在不完整状态下,新类(例如MyClass1)的超类列表可能尚未(尚未)在继承链上一直填充,而在使用类定义时,R 必须遍历继承链,并为班级填写了完整的家谱。当检查或安装一个包时,继承链必须是完整的——如果之前没有完成,它必须在install.packages步骤中。
如何查看元数据对象

使用getClass查看getClassDef给定类的元数据对象。

文档?getClass?getClassDef解释 R 搜索元数据对象的环境。需要注意的一个关键点是,至少必须先加载一个包,然后才能找到包中定义的类的元数据对象。

minweSpatialNULL这是我的玩具rgeosSpatialLinesNULL(请注意:

  • MyClass1知道它的所有父超类(通常情况),并且
  • SpatialLinesNULL(这是包中定义的一个类联合)几乎知道它所有的子,即使它自己根本不知道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知道的有点好奇,MyClass2因为它是 的子类MyClass1,但似乎没有直接提及MyClass1自己。我还没弄清楚为什么。

为什么超类列表会改变

当我除了添加到玩具包的说明文件中的指令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,并修改了该名称绑定到的对象中的元数据。它知道隐藏名称应该在哪里——它必须来自 package sp,因为来自SpatialLines类本身的元数据对象说明了它的父超类 ( Spatial) 所在的位置。元数据对象中祖先超类的完整规范包括一个package属性,该属性包含定义祖先超类的包的名称,以防两个现有加载的包恰好为一个类选择了相同的名称!

这就是importClassesFroming 缺失的超类起作用的原因——它将缺失的隐藏名称带入toy 包的imports:minweSpatialNULL环境中,从那里可以找到它们,并在必要时更新它们。minweSpatialNULL.findOrCopyClass

为什么.findOrCopy会发出警告

我想知道为什么.findOrCopyClass告诉我它找不到元数据对象,而它说的下一件事就是它正在我的包命名空间中制作副本!我在 r-devel 邮件列表中提出了这个问题,John Chambers 很友好地为我回答了这个问题(重点由我添加):

正如警告消息所暗示的那样,查找类定义的目的是更新新关系的条目。这要求保存定义的命名空间是可写的

在子类信息的情况下,如果不是当前正在加载的包,原始命名空间很可能被锁定。复制定义以更新子类信息似乎是唯一合理的选择,并且不需要警告消息。

修订版将省略此消息。

我剩下的概念问题与对象名称(例如函数或类(准确地说,函数对象或类元数据对象))与对象本身发生的情况之间的差异有关。或者换句话说,命名空间(可能锁定)是否需要更新,或者对象本身的(状态)是否需要更新。

事实证明, 'findorCopyClasses并不是在抱怨它找不到(未导出的)超类,而是它在可以更改超类值的地方找不到它。

锁定是什么意思

?base::bindenv文档说:

" 具有命名空间的包的命名空间环境在加载时被锁定。"

和一个锁定的环境意味着

" 防止在环境中添加或删除变量绑定。除非绑定已被锁定,否则仍然可以更改变量的值"

但是一些实验表明,除了包命名空间 环境被锁定外,imports:namespace 中的绑定也被锁定。锁定绑定意味着:

“无法更改锁定绑定的值”。

因此,由于超类元数据对象来自另一个包(例如rgeos),它在另一个包的名称空间中的绑定被锁定,因此它的值不能更改。或者就示例而言,当方法包想要添加Myclass1和到“拥有”的子类MyClass2列表时,它发现它不能,因为绑定(或者更准确地说,隐藏名称的绑定)被锁定。因此,关于需要制作副本的消息!SpatialLinesNULLSpatialLinesNULL.__C__SpatialLinesNULL

复制的替代方法可能是临时解锁 otherpackage 的名称空间中的绑定,更新对象并重新锁定绑定 - 但由于我刚刚了解锁定环境和绑定,我不知道这可能会产生什么后果是。我会一个人离开的。

好的,如果未导出所需的超类 ,如何破解解决方案

警告我没有测试这么多,无论如何这都是个主意,但如果你真的非常渴望让警告信息消失......

步骤1。查看警告消息并找到丢失的超类的(文本)名称,以及它来自的包。

第2步。用于classMetaName查找丢失的未导出超类的隐藏和损坏名称。对于超类MissingSuperclass,它可能是.__C__MissingSuperclass

第三步。在调用创建您自己的类之前,使用该:::方法访问元数据对象 (ie ) 并在属于您的包的适当环境中donorpackage:::.__C__MissingSuperclass为其指定适当的名称 (ie )。.__C__MissingSuperclasssetClass

正如我已经说过的,这是一个非常糟糕的主意,因为在脚上开枪是非常容易的,而且为什么还要麻烦,因为这基本上就是在警告消息发送.findOrCopyClasssetIs似乎要做的事情。

结束

如果你已经读到这里,我希望这对你有所帮助!我已经写了这么长的篇幅,主要是作为未来我的教程:-)

于 2015-03-12T12:46:56.700 回答
2

感谢您提出这个广泛的问题。我有两个改进它的建议。首先,提供一个可重现的示例,在这种情况下,它是一个最小的包,可以让我们重现您的警告或错误消息。例如,

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

在已sp加载的会话中工作正常,但在包代码中执行此操作时会出现问题。创建这样的包意味着做很多猜测工作:我们看不到您的 complete NAMESPACE,所以不知道您导出了什么,并且希望在加载您的包后在 R 会话中工作。第二:将您的问题与使用引起的问题隔离开来devtools(即使用构建和安装包的标准 R 包开发术语)。

根据您提供的信息,我只能回答:

  • Q1:Spatial不是虚拟类,它存在是因为它定义了所有派生类的共同点(CRS 和边界框),并且它是必需的,因为它定义了对所有派生类进行操作的方法。MyClass2需要它与您的包裹有关,我没有
  • Q2:我无法回答,因为您没有显示导致 Q1 的警告。此外,SpatialLinesNULL不是 的超类,Spatial而是 的超类SpatialLines,定义为

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

  • Q3:您可以尝试编译rgeos导出该类的修改版本;如果您提供了一个很好的用例(重现您的问题的最小包),其中一位开发人员rgeos将对其进行调查。

于 2015-03-05T18:00:38.513 回答