UseMethod("t") 告诉您t() 是一个 (S3) 通用函数,它具有用于不同对象类的方法。
S3方法调度系统
对于 S3 类,您可以使用 methods 函数列出特定通用函数或类的方法。
> methods(t)
[1] t.data.frame t.default t.ts*
Non-visible functions are asterisked
> methods(class="ts")
[1] aggregate.ts as.data.frame.ts cbind.ts* cycle.ts*
[5] diffinv.ts* diff.ts kernapply.ts* lines.ts
[9] monthplot.ts* na.omit.ts* Ops.ts* plot.ts
[13] print.ts time.ts* [<-.ts* [.ts*
[17] t.ts* window<-.ts* window.ts*
Non-visible functions are asterisked
“不可见的函数带有星号”表示该函数未从其包的命名空间中导出。您仍然可以通过::: 函数(即stats:::t.ts)或使用getAnywhere() 查看其源代码。 getAnywhere() 很有用,因为您不必知道函数来自哪个包。
> getAnywhere(t.ts)
A single object matching ‘t.ts’ was found
It was found in the following places
registered S3 method for t from namespace stats
namespace:stats
with value
function (x)
{
cl <- oldClass(x)
other <- !(cl %in% c("ts", "mts"))
class(x) <- if (any(other))
cl[other]
attr(x, "tsp") <- NULL
t(x)
}
<bytecode: 0x294e410>
<environment: namespace:stats>
S4方法调度系统
S4 系统是一种较新的方法调度系统,是 S3 系统的替代品。以下是 S4 函数的示例:
> library(Matrix)
Loading required package: lattice
> chol2inv
standardGeneric for "chol2inv" defined from package "base"
function (x, ...)
standardGeneric("chol2inv")
<bytecode: 0x000000000eafd790>
<environment: 0x000000000eb06f10>
Methods may be defined for arguments: x
Use showMethods("chol2inv") for currently available ones.
输出已经提供了很多信息。 standardGeneric 是 S4 功能的指示器。提供查看已定义 S4 方法的方法很有帮助:
> showMethods(chol2inv)
Function: chol2inv (package base)
x="ANY"
x="CHMfactor"
x="denseMatrix"
x="diagonalMatrix"
x="dtrMatrix"
x="sparseMatrix"
getMethod可以查看其中一种方法的源码:
> getMethod("chol2inv", "diagonalMatrix")
Method Definition:
function (x, ...)
{
chk.s(...)
tcrossprod(solve(x))
}
<bytecode: 0x000000000ea2cc70>
<environment: namespace:Matrix>
Signatures:
x
target "diagonalMatrix"
defined "diagonalMatrix"
还有每个方法的签名更复杂的方法,例如
require(raster)
showMethods(extract)
Function: extract (package raster)
x="Raster", y="data.frame"
x="Raster", y="Extent"
x="Raster", y="matrix"
x="Raster", y="SpatialLines"
x="Raster", y="SpatialPoints"
x="Raster", y="SpatialPolygons"
x="Raster", y="vector"
要查看这些方法之一的源代码,必须提供整个签名,例如
getMethod("extract" , signature = c( x = "Raster" , y = "SpatialPolygons") )
提供部分签名是不够的
getMethod("extract",signature="SpatialPolygons")
#Error in getMethod("extract", signature = "SpatialPolygons") :
# No method found for function "extract" and signature SpatialPolygons
调用未导出函数的函数
对于ts.union,.cbindts 和.makeNamesTs 是stats 命名空间中未导出的函数。您可以使用:::运算符或getAnywhere查看未导出函数的源代码。
> stats:::.makeNamesTs
function (...)
{
l <- as.list(substitute(list(...)))[-1L]
nm <- names(l)
fixup <- if (is.null(nm))
seq_along(l)
else nm == ""
dep <- sapply(l[fixup], function(x) deparse(x)[1L])
if (is.null(nm))
return(dep)
if (any(fixup))
nm[fixup] <- dep
nm
}
<bytecode: 0x38140d0>
<environment: namespace:stats>
调用编译代码的函数
请注意,“已编译”不是指由 compiler 包创建的字节编译的 R 代码。上面输出中的<bytecode: 0x294e410>行表示该函数是字节编译的,仍然可以从R命令行查看源代码。
调用 .C、.Call、.Fortran、.External、.Internal 或 .Primitive 的函数正在调用编译代码中的入口点,因此您必须查看编译代码的源代码如果您想完全了解该功能。 This R 源代码的 GitHub 镜像是一个不错的起点。 pryr::show_c_source 函数可能是一个有用的工具,因为它会直接将您带到 GitHub 页面以进行 .Internal 和 .Primitive 调用。包可以使用.C、.Call、.Fortran和.External;但不是.Internal 或.Primitive,因为它们用于调用内置于R 解释器中的函数。
对上述某些函数的调用可能会使用对象而不是字符串来引用编译后的函数。在这些情况下,对象属于"NativeSymbolInfo"、"RegisteredNativeSymbol" 或"NativeSymbol" 类;打印对象会产生有用的信息。例如,optim 调用.External2(C_optimhess, res$par, fn1, gr1, con)(注意这是C_optimhess,而不是"C_optimhess")。 optim 位于 stats 包中,因此您可以键入 stats:::C_optimhess 以查看有关正在调用的编译函数的信息。
包中的编译代码
如果你想查看一个包中的编译代码,你需要下载/解压包源。安装的二进制文件不够用。包的源代码可从最初安装包的同一 CRAN(或 CRAN 兼容)存储库中获得。 download.packages()函数可以为你获取包源。
download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")
这将下载Matrix包的源代码版本并将对应的.tar.gz文件保存在当前目录中。编译函数的源代码可以在未压缩和未去皮文件的src 目录中找到。解压缩和去皮步骤可以在R 之外完成,也可以在R 内使用untar() 函数完成。可以将下载和扩展步骤合并到一个调用中(注意,这种方式一次只能下载和解压一个包):
untar(download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")[,2])
或者,如果包开发是公开托管的(例如通过GitHub、R-Forge 或RForge.net),您可能可以在线浏览源代码。
基础包中的编译代码
某些软件包被视为“基础”软件包。这些软件包随 R 一起提供,并且它们的版本被锁定为 R 的版本。示例包括 base、compiler、stats 和 utils。因此,如上所述,它们不能作为 CRAN 上的单独可下载包提供。相反,它们是 /src/library/ 下各个包目录中 R 源代码树的一部分。下一节将介绍如何访问 R 源代码。
R 解释器内置的编译代码
如果您想查看 R 解释器内置的代码,您需要下载/解压 R 源代码;或者您可以通过 R Subversion repository 或 Winston Chang's github mirror 在线查看源代码。
Uwe Ligges 的 R news article (PDF)(第 43 页)是一个很好的通用参考,可以帮助您查看 .Internal 和 .Primitive 函数的源代码。基本步骤是先在src/main/names.c中查找函数名称,然后在src/main/*中的文件中查找“C-entry”名称。