博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何查看功能的源代码?
阅读量:2289 次
发布时间:2019-05-09

本文共 14611 字,大约阅读时间需要 48 分钟。

本文翻译自:

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: 我知道我可以通过在提示符下键入函数名称来打印该函数:

> tfunction (x) UseMethod("t")

In this case, what does UseMethod("t") mean? 在这种情况下, UseMethod("t")是什么意思? How do I find the source code that's actually being used by, for example: t(1:10) ? 如何找到例如t(1:10)实际使用的源代码?

Is there a difference between when I see UseMethod and when I see standardGeneric and showMethods , as with with ? 有没有当我看到之间的差异UseMethod ,当我看到standardGenericshowMethods ,与with

> withstandardGeneric for "with" defined from package "base"function (data, expr, ...) standardGeneric("with")
Methods may be defined for arguments: dataUse 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. 在其他情况下,我可以看到正在调用R函数,但是找不到这些函数的源代码。

> ts.unionfunction (..., dframe = FALSE) .cbind.ts(list(...), .makeNamesTs(...), dframe = dframe, union = TRUE)
> .cbindtsError: object '.cbindts' not found> .makeNamesTsError: object '.makeNamesTs' not found

How do I find functions like .cbindts and .makeNamesTs ? 如何找到.cbindts.makeNamesTs类的函数?

In still other cases, there's a bit of R code, but most of work seems to be done somewhere else. 在其他情况下,还有一些R代码,但是大多数工作似乎都在其他地方完成。

> matrixfunction (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)))}
> .Internalfunction (call) .Primitive(".Internal")> .Primitivefunction (name) .Primitive(".Primitive")

How do I find out what the .Primitive function does? 我如何找出.Primitive函数的作用? Similarly, some functions call .C , .Call , .Fortran , .External , or .Internal . 同样,一些函数调用.C.Call.Fortran.External ,或.Internal How can I find the source code for those? 我如何找到这些源代码?


#1楼

参考:


#2楼

UseMethod("t") is telling you that t() is a ( ) generic function that has methods for different object classes. UseMethod("t")告诉您t()是( )泛型函数,具有用于不同对象类的方法。

The S3 method dispatch system S3方法调度系统

For S3 classes, you can use the methods function to list the methods for a particular generic function or class. 对于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

"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 (ie stats:::t.ts ), or by using getAnywhere() . 您仍然可以通过:::函数(即stats:::t.ts )或使用getAnywhere()来查看其源代码。 getAnywhere() is useful because you don't have to know which package the function came from. getAnywhere()很有用,因为您不必知道函数来自哪个包。

> getAnywhere(t.ts)A single object matching ‘t.ts’ was foundIt was found in the following places  registered S3 method for t from namespace stats  namespace:statswith valuefunction (x) {    cl <- oldClass(x)    other <- !(cl %in% c("ts", "mts"))    class(x) <- if (any(other))         cl[other]    attr(x, "tsp") <- NULL    t(x)}

The S4 method dispatch system S4方法调度系统

The S4 system is a newer method dispatch system and is an alternative to the S3 system. S4系统是更新的方法调度系统,是S3系统的替代方法。 Here is an example of an S4 function: 这是一个S4函数的示例:

> library(Matrix)Loading required package: lattice> chol2invstandardGeneric for "chol2inv" defined from package "base"function (x, ...) standardGeneric("chol2inv")
Methods may be defined for arguments: xUse showMethods("chol2inv") for currently available ones.

The output already offers a lot of information. 输出已经提供了很多信息。 standardGeneric is an indicator of an S4 function. standardGeneric是S4功能的指示器。 The method to see defined S4 methods is offered helpfully: 查看定义的S4方法的方法很有帮助:

> showMethods(chol2inv)Function: chol2inv (package base)x="ANY"x="CHMfactor"x="denseMatrix"x="diagonalMatrix"x="dtrMatrix"x="sparseMatrix"

getMethod can be used to see the source code of one of the methods: getMethod可用于查看方法之一的源代码:

> getMethod("chol2inv", "diagonalMatrix")Method Definition:function (x, ...) {    chk.s(...)    tcrossprod(solve(x))}
Signatures: x target "diagonalMatrix"defined "diagonalMatrix"

There are also methods with more complex signatures for each method, for example 还有一些方法,每种方法的签名都比较复杂,例如

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"

To see the source code for one of these methods the entire signature must be supplied, eg 要查看这些方法之一的源代码,必须提供完整的签名,例如

getMethod("extract" , signature = c( x = "Raster" , y = "SpatialPolygons") )

It will not suffice to supply the partial signature 提供部分签名是不够的

getMethod("extract",signature="SpatialPolygons")#Error in getMethod("extract", signature = "SpatialPolygons") : #  No method found for function "extract" and signature SpatialPolygons

Functions that call unexported functions 调用未导出函数的函数

In the case of ts.union , .cbindts and .makeNamesTs are unexported functions from the stats namespace. 对于ts.union.cbindts.makeNamesTsstats名称空间中未导出的函数。 You can view the source code of unexported functions by using the ::: operator or getAnywhere . 您可以使用:::运算符或getAnywhere查看未导出函数的源代码。

> stats:::.makeNamesTsfunction (...) {    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}

Functions that call compiled code 调用已编译代码的函数

Note that "compiled" does not refer to byte-compiled R code as created by the compiler package. 请注意,“已编译”并不指代由编译器程序包创建的字节编译R代码。 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. 上面输出中的<bytecode: 0x294e410>行表明该函数是字节编译的,您仍然可以从R命令行查看源代码。

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. 函数调用.C.Call.Fortran.External.Internal ,或.Primitive在编译的代码调用入口点,所以你必须看看编译代码的来源,如果你想充分了解该功能。 GitHub mirror of the R source code is a decent place to start. 将R源代码GitHub的反射镜是一个体面的地方开始。 The function pryr::show_c_source can be a useful tool as it will take you directly to a GitHub page for .Internal and .Primitive calls. 函数pryr::show_c_source可能是一个有用的工具,因为它将直接带您到GitHub页面以进行.Internal.Primitive调用。 Packages may use .C , .Call , .Fortran , and .External ; 包可以使用.C.Call.Fortran.External ; but not .Internal or .Primitive , because these are used to call functions built into the R interpreter. 但不是.Internal.Primitive ,因为它们用于调用内置在R解释器中的函数。

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" ; 在这些情况下,该对象属于"NativeSymbolInfo""RegisteredNativeSymbol""NativeSymbol" and printing the object yields useful information. 打印对象会产生有用的信息。 For example, optim calls .External2(C_optimhess, res$par, fn1, gr1, con) (note that's C_optimhess , not "C_optimhess" ). 例如, optim调用.External2(C_optimhess, res$par, fn1, gr1, con) (请注意,这是C_optimhess ,而不是"C_optimhess" )。 optim is in the stats package, so you can type stats:::C_optimhess to see information about the compiled function being called. optim在stats包中,因此您可以键入stats:::C_optimhess以查看有关被调用的已编译函数的信息。

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. 可以从最初安装该软件包的同一CRAN(或与CRAN兼容)的存储库中获取软件包的源代码。 The download.packages() function can get the package source for you. download.packages()函数可以为您获取软件包源。

download.packages(pkgs = "Matrix",                   destdir = ".",                  type = "source")

This will download the source version of the Matrix package and save the corresponding .tar.gz file in the current directory. 这将下载Matrix包的源版本,并将相应的.tar.gz文件保存在当前目录中。 Source code for compiled functions can be found in the src directory of the uncompressed and untared file. 可以在未压缩和未压缩文件的src目录中找到已编译函数的源代码。 The uncompressing and untaring step can be done outside of R , or from within R using the untar() function. 可以在R外部或通过使用untar()函数在R内部完成解压缩和解压缩步骤。 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): 可以将下载和扩展步骤组合为一个调用(请注意,每次只能通过这种方式下载和解压缩一个包):

untar(download.packages(pkgs = "Matrix",                        destdir = ".",                        type = "source")[,2])

Alternatively, if the package development is hosted publicly (eg via , , or ), 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 , and utils . 这些软件包随R一起提供,并且它们的版本被锁定为R的版本。示例包括basecompilerstatsutils As such, they are not available as separate downloadable packages on CRAN as described above. 因此,如上所述,它们不能作为CRAN上的单独可下载软件包使用。 Rather, they are part of the R source tree in individual package directories under /src/library/ . 相反,它们是/src/library/下单个程序包目录中R源树的一部分。 How to access the R source is described in the next section. 下一节将介绍如何访问R源。

Compiled code built into the R interpreter R解释器中内置的已编译代码

If you want to view the code built-in to the R interpreter, you will need to download/unpack the R sources; 如果要查看R解释器内置的代码,则需要下载/解压缩R源。 or you can view the sources online via the R or . 或者您可以通过R 或在线查看源代码。

Uwe Ligges's (p. 43) is a good general reference of how to view the source code for .Internal and .Primitive functions. Uwe Ligges的 (p。43)是如何查看.Internal.Primitive函数源代码的很好的一般参考。 The basic steps are to first look for the function name in src/main/names.c and then search for the "C-entry" name in the files in src/main/* . 基本步骤是首先在src/main/names.c查找函数名称,然后在src/main/*中的文件中搜索“ C条目”名称。


#3楼

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. eg if we want the source for randomForest::rfcv() : 除了关于这个问题及其重复项的其他答案之外,这是一种获取包函数源代码的好方法,而无需知道它在哪个包中。例如,如果我们想要randomForest::rfcv()的源代码:

To view/edit it in a pop-up window: 要在弹出窗口中查看/编辑它:

edit(getAnywhere('rfcv'), file='source_rfcv.r')

To redirect to a separate file : 重定向到单独的文件

capture.output(getAnywhere('rfcv'), file='source_rfcv.r')

#4楼

It gets revealed when you debug using the debug() function. 使用debug()函数进行调试时,它会显示出来。 Suppose you want to see the underlying code in t() transpose function. 假设您想在t()转置函数中查看基础代码。 Just typing 't', doesn't reveal much. 仅输入“ t”并不会显示太多。

>t function (x) UseMethod("t")

But, Using the 'debug(functionName)', it reveals the underlying code, sans the internals. 但是,使用“ debug(functionName)”,它揭示了底层代码,而没有内部结构。

> debug(t)> t(co2)debugging in: t(co2)debug: UseMethod("t")Browse[2]> debugging in: t.ts(co2)debug: {    cl <- oldClass(x)    other <- !(cl %in% c("ts", "mts"))    class(x) <- if (any(other))         cl[other]    attr(x, "tsp") <- NULL    t(x)}Browse[3]> debug: cl <- oldClass(x)Browse[3]> debug: other <- !(cl %in% c("ts", "mts"))Browse[3]> debug: class(x) <- if (any(other)) cl[other]Browse[3]>  debug: attr(x, "tsp") <- NULLBrowse[3]> debug: t(x)

EDIT: debugonce() accomplishes the same without having to use undebug() 编辑: debugonce()完成相同操作,而不必使用undebug()


#5楼

There is a very handy function in R edit R edit有一个非常方便的功能

new_optim <- edit(optim)

It will open the source code of optim using the editor specified in R's options , and then you can edit it and assign the modified function to new_optim . 它将使用R options指定的编辑器打开optim的源代码,然后您可以对其进行编辑并将修改后的函数分配给new_optim I like this function very much to view code or to debug the code, eg, print some messages or variables or even assign them to a global variables for further investigation (of course you can use debug ). 我非常喜欢此功能来查看代码或调试代码,例如,打印一些消息或变量,甚至将它们分配给全局变量以进行进一步研究(当然您可以使用debug )。

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 如果您只想查看源代码,而又不想在控制台上打印烦人的长源代码,则可以使用

invisible(edit(optim))

Clearly, this cannot be used to view C/C++ or Fortran source code. 显然,这不能用于查看C / C ++或Fortran源代码。

BTW, edit can open other objects like list, matrix, etc, which then shows the data structure with attributes as well. 顺便说一句, edit可以打开其他对象,如列表,矩阵等,然后显示具有属性的数据结构。 Function de can be used to open an excel like editor (if GUI supports it) to modify matrix or data frame and return the new one. 函数de可用于打开一个类似Excel的编辑器(如果GUI支持),以修改矩阵或数据框并返回新的。 This is handy sometimes, but should be avoided in usual case, especially when you matrix is big. 有时这很方便,但是在通常情况下应避免使用,特别是当矩阵较大时。


#6楼

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 (eg, %% , %*% , %in% ), use getAnywhere , eg: 要查看某些基本中缀运算符的源代码(例如%%%*%%in% ),请使用getAnywhere ,例如:

getAnywhere("%%")# A single object matching ‘%%’ was found# It was found in the following places#   package:base#   namespace:base#  with value## function (e1, e2)  .Primitive("%%")

The main answer covers how to then use mirrors to dig deeper. 主要答案包括如何使用镜子进行更深入的研究。

转载地址:http://iscnb.baihongyu.com/

你可能感兴趣的文章
新一代数据查询语言GraphQL来啦
查看>>
Simple Zend_Layout Example
查看>>
The Zend Framework MVC Architecture
查看>>
Framework框架分析总结
查看>>
Windows7下centOS 硬盘安装双系统
查看>>
GRUB引导程序参数
查看>>
phpMyAdmin简明安装教程
查看>>
独立安装LAMP时需要注意的几点
查看>>
socket
查看>>
判断远程url是否有效的几种方法
查看>>
javascript中编写类似in_array()的原型函数
查看>>
go 数据库操作
查看>>
php读取二进制流
查看>>
Golang热重启
查看>>
热重启golang服务器(graceful restart golang http server)
查看>>
echo框架使用:获取与配置
查看>>
PHP模拟多进程并发将内容写入文件
查看>>
nginx.conf配置说明
查看>>
Eclipse设定和修改文件字符编码格式和换行符
查看>>
git常用操作以及快速入门教程
查看>>