如何查看函数的源代码?
我想查看一个函数的源代码以了解它是如何工作的。我知道我可以通过在提示符下键入函数名称来打印函数:
> t
function (x)
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>
在这种情况下,UseMethod("t")
是什么意思?如何找到实际使用的源代码,例如:t(1:10)
?
当我看到 UseMethod
时与看到 standardGeneric
和 showMethods
时(与 with
一样)是否有区别?
> with
standardGeneric for "with" defined from package "base"
function (data, expr, ...)
standardGeneric("with")
<bytecode: 0x102fb3fc0>
<environment: 0x102fab988>
Methods may be defined for arguments: data
Use showMethods("with") for currently available ones.
在其他情况下,我可以看到正在调用 R 函数,但我找不到这些函数的源代码。
> ts.union
function (..., dframe = FALSE)
.cbind.ts(list(...), .makeNamesTs(...), dframe = dframe, union = TRUE)
<bytecode: 0x36fbf88>
<environment: namespace:stats>
> .cbindts
Error: object '.cbindts' not found
> .makeNamesTs
Error: object '.makeNamesTs' not found
如何找到 .cbindts
和 .makeNamesTs
等函数?
还有一些情况,有一些 R 代码,但大部分工作似乎是在其他地方完成的。
> matrix
function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
{
if (is.object(data) || !is.atomic(data))
data <- as.vector(data)
.Internal(matrix(data, nrow, ncol, byrow, dimnames, missing(nrow),
missing(ncol)))
}
<bytecode: 0x134bd10>
<environment: namespace:base>
> .Internal
function (call) .Primitive(".Internal")
> .Primitive
function (name) .Primitive(".Primitive")
如何了解 .Primitive
函数的作用?同样,某些函数调用 .C
、.Call
、.Fortran
、.External
或 。内部
。我怎样才能找到这些的源代码?
I want to look at the source code for a function to see how it works. I know I can print a function by typing its name at the prompt:
> t
function (x)
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>
In this case, what does UseMethod("t")
mean? How do I find the source code that's actually being used by, for example: t(1:10)
?
Is there a difference between when I see UseMethod
and when I see standardGeneric
and showMethods
, as with with
?
> with
standardGeneric for "with" defined from package "base"
function (data, expr, ...)
standardGeneric("with")
<bytecode: 0x102fb3fc0>
<environment: 0x102fab988>
Methods may be defined for arguments: data
Use showMethods("with") for currently available ones.
In other cases, I can see that R functions are being called, but I can't find the source code for those functions.
> ts.union
function (..., dframe = FALSE)
.cbind.ts(list(...), .makeNamesTs(...), dframe = dframe, union = TRUE)
<bytecode: 0x36fbf88>
<environment: namespace:stats>
> .cbindts
Error: object '.cbindts' not found
> .makeNamesTs
Error: object '.makeNamesTs' not found
How do I find functions like .cbindts
and .makeNamesTs
?
In still other cases, there's a bit of R code, but most of work seems to be done somewhere else.
> matrix
function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
{
if (is.object(data) || !is.atomic(data))
data <- as.vector(data)
.Internal(matrix(data, nrow, ncol, byrow, dimnames, missing(nrow),
missing(ncol)))
}
<bytecode: 0x134bd10>
<environment: namespace:base>
> .Internal
function (call) .Primitive(".Internal")
> .Primitive
function (name) .Primitive(".Primitive")
How do I find out what the .Primitive
function does? Similarly, some functions call .C
, .Call
, .Fortran
, .External
, or .Internal
. How can I find the source code for those?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
UseMethod("t")
告诉您t()
是 ( S3)通用函数,具有针对不同对象类的方法。S3 方法调度系统
对于 S3 类,您可以使用
methods
函数列出特定泛型函数或类的方法。“不可见函数带有星号”表示该函数未从其包的命名空间中导出。您仍然可以通过
:::
函数(即stats:::t.ts
)或使用getAnywhere()
查看其源代码>。getAnywhere()
很有用,因为您不必知道该函数来自哪个包。S4 方法调度系统
S4 系统是一种较新的方法调度系统,是 S3 系统的替代方案。以下是 S4 函数的示例:
输出已经提供了大量信息。
standardGeneric
是 S4 功能的指示符。提供了查看已定义 S4 方法的方法,很有帮助:getMethod
可用于查看其中一种方法的源代码:还有每个方法具有更复杂签名的方法,例如,
查看这些方法之一的源代码必须提供整个签名,例如,
提供部分签名是不够的。
调用未导出函数的函数
在
ts.union
、.cbindts<的情况下/代码>和 .makeNamesTs 是来自
stats
命名空间的未导出函数。您可以使用:::
运算符或getAnywhere
查看未导出函数的源代码。调用编译代码的函数
请注意,“编译”并不是指由编译器包创建的字节编译 R 代码。上面输出中的
行表示该函数是字节编译的,您仍然可以从 R 命令行查看源代码。调用
.C
、.Call
、.Fortran
、.External
、.Internal 或 .Primitive 正在调用已编译代码中的入口点,因此如果您想完全理解该函数,则必须查看已编译代码的源代码。 这个 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()
函数可以为您获取包源。这将下载 Matrix 包的源版本并将相应的 .tar.gz 文件保存在当前目录中。已编译函数的源代码可以在未压缩和解压文件的
src
目录中找到。解压缩和解压步骤可以在R
外部完成,也可以在R
内部使用untar()
函数完成。可以将下载和扩展步骤合并到一个调用中(请注意,通过这种方式一次只能下载和解压一个包):或者,如果包开发是公开托管的(例如通过 GitHub, R-Forge 或 RForge.net),您可以在线浏览源代码。
基础包中的已编译代码
某些包被视为“基础”包。这些软件包随 R 一起提供,其版本锁定为 R 版本。示例包括
base
、compiler
、stats
和utils
。因此,如上所述,它们不能在 CRAN 上作为单独的可下载包提供。相反,它们是/src/library/
下各个包目录中 R 源代码树的一部分。下一节将介绍如何访问 R 源。R 解释器中内置的编译代码
如果您想查看 R 解释器中内置的代码,您将需要下载/解压 R 源代码;或者您可以通过 R Subversion 存储库 或 Winston Chang 的 github 镜像。
Uwe Ligges 的 R 新闻文章 (PDF)(第 43 页)是关于如何查看
.Internal
和.Primitive
函数源代码的很好的一般参考。基本步骤是首先在 src/main/names.c 中查找函数名称,然后在 src/main/*< 中的文件中搜索“C-entry”名称/代码>。UseMethod("t")
is telling you thatt()
is a (S3) generic function that has methods for different object classes.The S3 method dispatch system
For S3 classes, you can use the
methods
function to list the methods for a particular generic function or class."Non-visible functions are asterisked" means the function is not exported from its package's namespace. You can still view its source code via the
:::
function (i.e.stats:::t.ts
), or by usinggetAnywhere()
.getAnywhere()
is useful because you don't have to know which package the function came from.The S4 method dispatch system
The S4 system is a newer method dispatch system and is an alternative to the S3 system. Here is an example of an S4 function:
The output already offers a lot of information.
standardGeneric
is an indicator of an S4 function. The method to see defined S4 methods is offered helpfully:getMethod
can be used to see the source code of one of the methods:There are also methods with more complex signatures for each method, for example
To see the source code for one of these methods the entire signature must be supplied, e.g.
It will not suffice to supply the partial signature
Functions that call unexported functions
In the case of
ts.union
,.cbindts
and.makeNamesTs
are unexported functions from thestats
namespace. You can view the source code of unexported functions by using the:::
operator orgetAnywhere
.Functions that call compiled code
Note that "compiled" does not refer to byte-compiled R code as created by the compiler package. The
<bytecode: 0x294e410>
line in the above output indicates that the function is byte-compiled, and you can still view the source from the R command line.Functions that call
.C
,.Call
,.Fortran
,.External
,.Internal
, or.Primitive
are calling entry points in compiled code, so you will have to look at sources of the compiled code if you want to fully understand the function. This GitHub mirror of the R source code is a decent place to start. The functionpryr::show_c_source
can be a useful tool as it will take you directly to a GitHub page for.Internal
and.Primitive
calls. Packages may use.C
,.Call
,.Fortran
, and.External
; but not.Internal
or.Primitive
, because these are used to call functions built into the R interpreter.Calls to some of the above functions may use an object instead of a character string to reference the compiled function. In those cases, the object is of class
"NativeSymbolInfo"
,"RegisteredNativeSymbol"
, or"NativeSymbol"
; and printing the object yields useful information. For example,optim
calls.External2(C_optimhess, res$par, fn1, gr1, con)
(note that'sC_optimhess
, not"C_optimhess"
).optim
is in the stats package, so you can typestats:::C_optimhess
to see information about the compiled function being called.Compiled code in a package
If you want to view compiled code in a package, you will need to download/unpack the package source. The installed binaries are not sufficient. A package's source code is available from the same CRAN (or CRAN compatible) repository that the package was originally installed from. The
download.packages()
function can get the package source for you.This will download the source version of the Matrix package and save the corresponding
.tar.gz
file in the current directory. Source code for compiled functions can be found in thesrc
directory of the uncompressed and untared file. The uncompressing and untaring step can be done outside ofR
, or from withinR
using theuntar()
function. It is possible to combine the download and expansion step into a single call (note that only one package at a time can be downloaded and unpacked in this way):Alternatively, if the package development is hosted publicly (e.g. via GitHub, R-Forge, or RForge.net), you can probably browse the source code online.
Compiled code in a base package
Certain packages are considered "base" packages. These packages ship with R and their version is locked to the version of R. Examples include
base
,compiler
,stats
, andutils
. As such, they are not available as separate downloadable packages on CRAN as described above. Rather, they are part of the R source tree in individual package directories under/src/library/
. How to access the R source is described in the next section.Compiled code built into the R interpreter
If you want to view the code built-in to the R interpreter, you will need to download/unpack the R sources; or you can view the sources online via the R Subversion repository or Winston Chang's github mirror.
Uwe Ligges's R news article (PDF) (p. 43) is a good general reference of how to view the source code for
.Internal
and.Primitive
functions. The basic steps are to first look for the function name insrc/main/names.c
and then search for the "C-entry" name in the files insrc/main/*
.除了这个问题及其重复项的其他答案之外,这里还有一个获取包函数源代码的好方法,而无需知道它位于哪个包中。
例如,如果我们想要
randomForest::rfcv()
的源代码:要在弹出窗口中查看/编辑它:
请注意
edit()< /code> 打开文本编辑器(用户选择的),而
View()
调用电子表格样式的数据查看器。View()
非常适合浏览(多列)数据,但通常对于除玩具长度之外的任何代码 都很糟糕。edit()
在我看来实际上比View()
好得多,因为使用edit()
你可以折叠/隐藏/虚拟出所有 arg-parsing/checking/default/error-message 逻辑,这些逻辑可能占用 R 函数的 70%,并且只到达函数实际运行的部分某事(!),什么它的返回类型是对象的类型,是否以及如何递归等。重定向到一个单独的文件(这样你就可以在你最喜欢的 IDE/编辑器中调出代码/处理它grep/等):
In addition to the other answers on this question and its duplicates, here's a good way to get source code for a package function without needing to know which package it's in.
e.g. say if we want the source for
randomForest::rfcv()
:To view/edit it in a pop-up window:
Note that
edit()
opens a text editor (of user's choice), whereasView()
invokes a spreadsheet-style data viewer.View()
is great for browsing (multi-columnar) data, but usually terrible for code of anything other than toy length.edit()
is IMO actually far better thanView()
, since withedit()
you can collapse/hide/dummy out all the arg-parsing/checking/default/error-message logic which can take up to 70% of an R function, and just get to the part where the function actually operationally does something(!), what type(s) of objects its return type is, whether and how it recurses, etc.To redirect to a separate file (so you can bring up the code in your favorite IDE/editor/process it with grep/etc.):
对于非原始函数,R 基类包含一个名为
body()
的函数,它返回函数体。例如,可以查看print.Date()
函数的源代码:将产生以下结果:
如果您正在编写脚本并希望将函数代码作为字符向量,则可以获取它。
会让你明白:
我为什么要做这样的事?我正在基于列表创建一个自定义 S3 对象(
x
,其中class(x) = "foo"
)。列表成员之一(名为“fun”)是一个函数,我希望print.foo()
显示缩进的函数源代码。因此,我最终在print.foo()
中得到了以下代码片段:它缩进并显示与
x[["fun"]]
关联的代码。编辑 2020-12-31
获取源代码的相同
字符
向量的一种不太迂回的方法是:For non-primitive functions, R base includes a function called
body()
that returns the body of function. For instance the source of theprint.Date()
function can be viewed:will produce this:
If you are working in a script and want the function code as a character vector, you can get it.
will get you:
Why would I want to do such a thing? I was creating a custom S3 object (
x
, whereclass(x) = "foo"
) based on a list. One of the list members (named "fun") was a function and I wantedprint.foo()
to display the function source code, indented. So I ended up with the following snippet inprint.foo()
:which indents and displays the code associated with
x[["fun"]]
.Edit 2020-12-31
A less circuitous way to get the same
character
vector of source code is:当您使用 debug() 函数进行调试时,它就会显示出来。
假设您想查看 t() 转置函数中的底层代码。只是输入“t”,并不能透露太多信息。
但是,使用“debug(functionName)”,它揭示了底层代码,没有内部结构。
编辑:
debugonce() 可以完成相同的任务,而无需使用 undebug()
It gets revealed when you debug using the debug() function.
Suppose you want to see the underlying code in t() transpose function. Just typing 't', doesn't reveal much.
But, Using the 'debug(functionName)', it reveals the underlying code, sans the internals.
EDIT:
debugonce() accomplishes the same without having to use undebug()
没有看到这如何适合主要答案的流程,但它困扰了我一段时间,所以我在这里添加它:
中缀运算符
查看一些基本中缀运算符的源代码(例如,
%%< /code>,
%*%
,%in%
),使用getAnywhere
,例如:主要答案包括如何使用镜子进行挖掘更深。
Didn't see how this fit into the flow of the main answer but it stumped me for a while so I'm adding it here:
Infix Operators
To see the source code of some base infix operators (e.g.,
%%
,%*%
,%in%
), usegetAnywhere
, e.g.:The main answer covers how to then use mirrors to dig deeper.
在 RStudio 中,有(至少)3 种方法:
Ctrl 或 Command
View
(function_name)(如上所述)将打开一个包含源代码的新窗格。如果您到达 .Primitive 或 .C,您将需要另一种方法,抱歉。
In RStudio, there are (at least) 3 ways:
Ctrl or Command
View
(function_name) (as stated above)A new pane will open with the source code. If you reach .Primitive or .C you'll need another method, sorry.
R中有一个非常方便的函数
edit
,它会使用R的
options
中指定的编辑器打开optim
的源代码,然后你就可以编辑它并将修改后的函数分配给new_optim
。我非常喜欢这个功能来查看代码或调试代码,例如打印一些消息或变量,甚至将它们分配给全局变量以进行进一步调查(当然您可以使用debug
)。如果您只是想查看源代码,并且不想在控制台上打印烦人的长源代码,您可以使用
Clearly,这不能用于查看 C/C++ 或 Fortran 源代码。
顺便说一句,
edit
可以打开其他对象,如列表、矩阵等,然后也显示带有属性的数据结构。函数de
可用于打开类似Excel的编辑器(如果GUI支持的话)来修改矩阵或数据框并返回新的。有时这很方便,但在通常情况下应该避免,特别是当矩阵很大时。There is a very handy function in R
edit
It will open the source code of
optim
using the editor specified in R'soptions
, and then you can edit it and assign the modified function tonew_optim
. I like this function very much to view code or to debug the code, e.g, print some messages or variables or even assign them to a global variables for further investigation (of course you can usedebug
).If you just want to view the source code and don't want the annoying long source code printed on your console, you can use
Clearly, this cannot be used to view C/C++ or Fortran source code.
BTW,
edit
can open other objects like list, matrix, etc, which then shows the data structure with attributes as well. Functionde
can be used to open an excel like editor (if GUI supports it) to modify matrix or data frame and return the new one. This is handy sometimes, but should be avoided in usual case, especially when you matrix is big.只要该函数是用纯 R 而不是 C/C++/Fortran 编写的,就可以使用以下内容。否则,最好的方法是调试并使用“跳转 进入”:
As long as the function is written in pure R not C/C++/Fortran, one may use the following. Otherwise the best way is debugging and using "jump into":
View(function_name)
- 例如。View(mean)
确保使用大写 [V]。只读代码将在编辑器中打开。View(function_name)
- eg.View(mean)
Make sure to use uppercase [V]. The read-only code will open in the editor.您还可以尝试使用 S3 通用的
print.function()
将函数写入控制台。You can also try to use
print.function()
, which is S3 generic, to get the function write in the console.要查看该函数的源代码,请使用 print()
To see the source code of the function use print()
首先,尝试在不使用
()
的情况下运行该函数示例:让我们获取
cat()
函数的源代码:但有时会返回“UseMethod”而不是源代码
如果我们尝试获取
read_xml()
的源代码:这对我们来说没有多大用处!在本例中,看一下这些方法:
并对上面的值使用 getAnywhere 来查看源代码:
另一个示例
让我们尝试查看
qqnorm()
的源代码:First, try running the function without
()
Example: let's get the source code for the
cat()
function:But sometimes that will return "UseMethod" instead of source code
If we try to get the source code for
read_xml()
:That's not much use to us! In this case, take a look at the methods:
And use getAnywhere on the value(s) above to see the source code:
Another example
Let's try to see the source code for
qqnorm()
:PyCharm 中 R 插件的快速解决方案(对于 RStudio,请参阅 @Arthur Yip 的答案)。
如有必要,在编辑器或 R 控制台中键入并选择函数名称。然后“转到声明”或使用快捷键 CTRL-B 或 Command-B。
注意:这对于
.Primitive
(即内部实现的)函数没有用。A quick solution for the R-plugin in PyCharm (for RStudio, see the answer by @Arthur Yip).
Type, if necessary, and select the function name in the Editor or R Console. Then "Go to Declaration" or use shortcuts CTRL-B or Command-B.
Note: this is not useful for
.Primitive
(ie, internally implemented) functions.您可以通过运行不带括号的函数来查看函数的源代码
()
或
您可以输入类似
View(function_name)
的函数,例如:
you can view the source code of the function from run the function without brackets
()
or
you can type function like
View(function_name)
eg: