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")
调用未导出函数的函数
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
的函数是在编译代码中调用入口点,因此如果您想完全理解该函数,就必须查看编译代码的源代码。这个 R 源代码的 GitHub 镜像是一个不错的起点。函数 pryr::show_c_source
可以是一个有用的工具,因为它会直接带您到 .Internal
和 .Primitive
调用的 GitHub 页面。包可能使用 .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
外部完成,也可以使用untar()
函数在R
中完成。可以将下载和扩展步骤合并为一次调用(请注意,只能以这种方式下载和解压缩一个软件包):
untar(download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")[,2])
如果软件包的开发是公开托管的(例如通过GitHub,R-Forge或RForge.net),您可以在网上浏览源代码。
基本软件包中的编译代码
某些软件包被认为是“基本”软件包。这些软件包与R一起发布,并且其版本锁定为R的版本。例如,它们包括base
,compiler
,stats
和utils
。因此,它们不像上面描述的那样作为单独可下载的软件包在CRAN上提供。相反,它们是R源树中的个别软件包目录下的一部分,在/src/library/
下。如何访问R源在下一节中介绍。
内置于R解释器中的编译代码
如果要查看内置于R解释器中的代码,则需要下载/解压缩R源代码;或者您可以通过R Subversion存储库或Winston Chang的github镜像在线查看源代码。
Uwe Ligges的R新闻文章(PDF)(第43页)是查看.Internal
和.Primitive
函数源代码的良好参考。基本步骤是首先在src/main/names.c
中查找函数名称,然后在src/main/*
文件中搜索“C-entry”名称。