序号

方法

适用情况

例子

1

运行函数名称

自定义函数、简单的未封装函数

lm / matrix

2

针对 S3 类型的函数,运行methods("函数名") 查看有哪些具体的函数对于不带星号的函数,运行具体的函数名,对于带星号*的 不可见 函数运行getAnywhere("具体的函数名")

输入函数名之后显示有 UseMethod("函数名") 一行则说明是 S3 类型

methods("plot") + plot.default / getAnywhere("plot.factor")

3

针对 S4 类型的函数,运行showMethods("函数名") 查看有哪些方法,再使用 getMethod("函数名", signature="方法名")

输入函数名之后显示有 Use showMethods("函数名") 一行则说明是 S4 类型

showMethods("show") + getMethod("show", "mle")

4

针对未导出/内部的函数(unexported functions) ,使用 包名:::函数名,或者getAnywhere("函数名")

使用方法1查看源代码的过程中会碰到调用了某些“不存在的”函数,因为这些函数只在包的内部使用。比如在基础包 stats 里面 ts.union 函数的源代码有 .cbindts.makeNamesTs 这两个以.开头的内部函数

stats:::.cbindts / getAnywhere(".makeNamesTs")

5

针对已编译的代码(compiled code,这里指 R 原生调用 C / Fortran 等其他编程语言的代码或者 R interpreter 内置的基础函数) ,先下载源代码版本的 R 到一个目录 R_HOME,然后在$R_HOME/src/main/names.c 中查找函数,再在$R_HOME/src/main 或者 $R_HOME/src目录下查找相应的源码3

这类函数的特点是:输入函数名后的源码里面调用了.C .Call .Fortran .External 或 .Internal .Primitive 这类函数

命令行输入 sum 看到出现 .Primitive("sum"),这意味着调用了内部的函数(entry point),查找上述的 names.c 文件可以看到一行 {"sum", do_summary, ... },可以发现在相同目录下有 summary.c 文件,那么 sum 函数的源代码就在此文件里面;如果看到不易识别的 do_... ,则需要在 $R_HOME/src/ 路径下搜索可能的文件名,一个例子见下面的补充 5

6

针对安装包的源码,可以使用 download() 和 untar() 下载解压源码文件进行查看

查看所加载的第三方包的完整源代码

untar(download.packages(pkgs = "Matrix", destdir = ".", type = "source")[,2]) 下载并解压“matrix”包到当前工作目录,源码在 src 下

补充:

  1. 以上的 func("函数名", ...) 可以写成 func(函数名, ...)
  2. methods() 其实可以把 S3 和 S4 泛型函数(generic function)与类(class)都查找出来,因此是非常实用的函数。但是你如果用它找 S4 类型函数,会发现返回结果是罗列方法名称,要获得 S4 的 signature,则需使用 showMethods()
  3. 有些 S4 类型的 signature 带多个参数,比如plot 函数也有S4 类型,使用showMethods(“plot”), 发现有 x=“profile.mle”, y=“missing” 方法,因此可以使用c() 将用多个参数描述的方法“打包”查询:getMethod(plot, signature = c(x="profile.mle", y="missing"))
  4. 如果不在命令行查看源代码,想打开新窗口查看/注释修改输出源代码文件,可使用page() / edit() 函数,如 page(getMethod(“show”, “mle”)) 或者 edit(getAnywhere(".makeNamesTs"))
  5. 查看 names.c 文件发现有一类基础的数学/统计函数,比如二项分布 {"pbinom", do_math3, ... } ,调用了 math 文件,本地搜索“math”或者“pbinom”,发现 src/nmath/ 文件和下面的 pbinom.c 源码文件。
  6. 内置包 base, compiler, stats, utils 在 CRAN 上找不到下载地址,因为每个安装好(本地版本)的 R 是编译过的二进制软件,无法查看到“源代码”。