【问题标题】:How to tell what method is being used by a function call when `methods` fails?当`methods`失败时,如何判断函数调用正在使用什么方法?
【发布时间】:2015-11-29 23:46:05
【问题描述】:

还不如让猫从袋子里出来,说我已经尝试了大约一天来弄清楚当我为 SpatialPolygons* 类的对象调用 plot 时发生了什么。我的直觉是寻找plot.SpatialPolygonsDataFrame,这种方法适用于我见过和遇到的任何其他示例,但都失败了。

快速示例:

US States .shp file 在这里。

library(maptools)
us.states<-readShapePoly("cb_2014_us_state_5m.shp")
plot(us.states)

有点笨拙,但不管怎样——关键是对plot 和深层R 的简单调用就知道调用哪个方法来为我们提供所有形状的表示。

经过一番搜索,我尝试了各种 SO Q&As 建议的其他两种方法,首先是:

> methods(plot)
 [1] plot.aareg*                         plot.acf*                          
 [3] plot,ANY,ANY-method                 plot.cox.zph*                      
 [5] plot.data.frame*                    plot.decomposed.ts*                
 [7] plot.default                        plot.dendrogram*                   
 [9] plot.density*                       plot.ecdf                          
[11] plot.factor*                        plot.formula*                      
[13] plot.function                       plot.hclust*                       
[15] plot.histogram*                     plot.HoltWinters*                  
[17] plot.isoreg*                        plot.lm*                           
[19] plot.medpolish*                     plot.mlm*                          
[21] plot.ppr*                           plot.prcomp*                       
[23] plot.princomp*                      plot.profile.nls*                  
[25] plot.raster*                        plot.shingle*                      
[27] plot,SpatialGrid,missing-method     plot,SpatialLines,missing-method   
[29] plot,Spatial,missing-method         plot,SpatialPixels,missing-method  
[31] plot,SpatialPoints,missing-method   plot,SpatialPolygons,missing-method
[33] plot.spec*                          plot.spline*                       
[35] plot.stepfun                        plot.stl*                          
[37] plot.survfit*                       plot.table*                        
[39] plot.times*                         plot.trellis*                      
[41] plot.ts                             plot.tskernel*                     
[43] plot.TukeyHSD*                      plot.xyVector*                     
[45] plot.zoo*                              

答案似乎在插槽 27-32;然而,每一个后面都有一个令人烦恼的逗号!没有提到这在?methods 中是可能的,?plot,SpatialPolygons,missing-method 是一个错误。快速搜索missing-method 没有任何用处,?methods 中也没有提及。

好的;继续。 getS3method 呢? getMethod? getMethods? getAllMethods??

> getS3method("plot","SpatialPolygonsDataFrame")
Error in getS3method("plot", "SpatialPolygonsDataFrame") : 
  S3 method 'plot.SpatialPolygonsDataFrame' not found

> getMethod("plot","SpatialPolygonsDataFrame")
Error in getMethod("plot", "SpatialPolygonsDataFrame") : 
  no method found for function 'plot' and signature SpatialPolygonsDataFrame

后两者已被弃用,也不返回任何内容。

显然,这些功能只是我第一直觉的替代品。

那么现在呢?当传递SpatialPolygonsDataFrame 时,如何判断plot 正在调用哪个方法?是否有任何通用方法可以替代我上面使用的方法来解决这个问题?

编辑:

我偶然发现了this (=?`Spatial-Polygons-class` ),上面写着:

空间多边形的plot 方法采用以下参数:

但它仍然没有确切说明该方法是什么。

【问题讨论】:

  • ?methods 中提到了“烦人的逗号”Details 部分的第二段说,“S4 方法签名打印为 'generic,class-method';S4 允许多次分派,因此签名中可能有多个类 'generic,A ,B-方法'。”。以及如何查看 S4 方法的源代码在How can I view the source code for a function?的回答中有所描述。
  • 澄清一下,methods 函数从未“告诉你使用了哪种方法”。它只告诉你加载的包中有哪些方法可用。

标签: r oop methods maptools


【解决方案1】:

部分答案:方法是sp:::plot.SpatialPolygons。我不知道为什么这些逗号会出现在methods(plot) 的结果中; plot,SpatialPolygons,missing-method 对我来说毫无意义(我也看到了)。

我通过引发错误找到了答案。我没有你的形状文件,所以我从help("SpatialPolygonsDataFrame-class") 中获取了示例,我从?SpatialPolygons" 中获取了该示例。示例如下:

Sr1 = Polygon(cbind(c(2,4,4,1,2),c(2,3,5,4,2)))
Sr2 = Polygon(cbind(c(5,4,2,5),c(2,3,2,2)))
Sr3 = Polygon(cbind(c(4,4,5,10,4),c(5,3,2,5,5)))
Sr4 = Polygon(cbind(c(5,6,6,5,5),c(4,4,3,3,4)), hole = TRUE)
Srs1 = Polygons(list(Sr1), "s1")
Srs2 = Polygons(list(Sr2), "s2")
Srs3 = Polygons(list(Sr3, Sr4), "s3/4")
SpP = SpatialPolygons(list(Srs1,Srs2,Srs3), 1:3)
plot(SpP, col = 1:3, pbg="white")

然后我更改了绘图调用以给出错误:

plot(SpP, col = kasjdhfkjasdfhkas, pbg = "white")
# Error in plot.SpatialPolygons(x, ...) : object 'kasjdhfkjasdfhkas' not found

(除非您在工作区中将kasjdhfkjasdfhkas 定义为向量,否则应该可以使用)。果然,

sp:::plot.SpatialPolygons

显示了方法的代码。

【讨论】:

  • 这些都是很好的答案——如果将来遇到类似问题,你的肯定会提供一些很好的调查工具。谢谢。
【解决方案2】:

回答 Gregor 提出的几个问题。 methods 函数以前不显示 S4 方法的结果,但现在可以了。在 NEWS 文档中进行搜索,我发现这是在 3.2.0 版中添加的:

methods() reports S4 in addition to S3 methods; output is simplified when the class 
argument is used. .S3methods() and methods::.S4methods() report S3 and S4 methods separately.

SpatialPolygons 是 S4 对象,因此具有调度的槽和 S4 方法。您可以通过以下方式显示 S4 方法:

showMethods(f='plot', classes='SpatialPolygons', includeDefs=TRUE)
#    ---- result ---
Function: plot (package graphics)
x="SpatialPolygons", y="missing"
function (x, y, ...) 
plot.SpatialPolygons(x, ...)

这告诉您该类有一个 S4 函数。您可以执行sp:::SpatialPolygonsgetAnywhere(plot.SpatialPolygons) 来查看函数代码。 (通常使用includeDefs=TRUE 的调用会显示R 代码,但此处不显示。)methods(plot) 在加载包'sp' 时的结果告诉您,在工作区中注册了8 种不同的绘图S4 方法。逗号后面的项目是用于函数调度的“签名”。 “missing-method”是指不指定第二个参数的情况,其中在函数体内执行的missing函数会返回TRUE

  [1] plot,ANY,ANY-method                 plot,color,ANY-method              
  [3] plot,Spatial,missing-method         plot,SpatialGrid,missing-method    
  [5] plot,SpatialLines,missing-method    plot,SpatialPixels,missing-method  
  [7] plot,SpatialPoints,missing-method   plot,SpatialPolygons,missing-method

这将向您展示当传递给它的对象不匹配任何 S4 方法时,然后用于调度 plot-call 的内容:

showMethods(f='plot', classes='ANY', includeDefs=TRUE)
Function: plot (package graphics)
x="ANY", y="ANY"
function (x, y, ...) 
UseMethod("plot")


x="color", y="ANY"
function (x, y, ...) 
{
    .local <- function (x, y, pch = 20, cex = 3) 
    pairs(coords(x), col = hex(x, fix = TRUE), pch = pch, cex = cex)
    .local(x, y, ...)
}

基本上,R 解释器首先会检查是否有任何 S4 方法是合适的,如果失败,将开始遍历 S3 方法,直到到达 plot.default

> getMethod(f='plot', signature=c(x='SpatialPolygons', y='missing'))
Method Definition:

function (x, y, ...) 
plot.SpatialPolygons(x, ...)
<environment: namespace:sp>

Signatures:
        x                 y        
target  "SpatialPolygons" "missing"
defined "SpatialPolygons" "missing"

顺便说一句,我在?getMethods 的回复中看到了这一点:

## Deprecated in 2010 and defunct in 2015 for \code{table = FALSE}:
getMethods(f, where, table = FALSE)

【讨论】:

  • 知道为什么它说缺少方法,即使在专门加载 sp 时也是如此?我对答案的最初反应是,这是 maptools 调用 sp 函数,即使我没有直接加载 sp...
  • @MichaelChirico:“缺失”并不意味着该方法缺失。它是签名中的一种特殊类型(另一个是“ANY”)。
  • @joshuaulrich 是故意混淆还是只是我?
  • ?methods 记录逗号:“S4 方法签名打印为 'generic,class-method';S4 允许多次调度,因此签名中可能有多个类 'generic,A,B -方法'”。 includeDefs=TRUE 确实 显示 R 代码 -- sp:::plot.SpatialPolygons。 selectMethod(plot, c("SpatialPolygonsDataFrame", "missing")) 类似于 getMethod(),但考虑了继承。它表示“目标”和“定义”方法;定义好的方法在手,帮助页面是methods(plot)返回的方法名,?"plot,SpatialPolygons,missing-method"
猜你喜欢
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 2023-03-31
  • 2010-12-16
  • 2023-03-07
相关资源
最近更新 更多