R 如何查看函数的源代码?
我想看看函数的源代码,看看它是如何工作的。我知道我可以通过在提示符处键入函数名来打印函数:R 如何查看函数的源代码?,r,function,r-faq,R,Function,R Faq,我想看看函数的源代码,看看它是如何工作的。我知道我可以通过在提示符处键入函数名来打印函数: > t function (x) UseMethod("t") <bytecode: 0x2332948> <environment: namespace:base> 在其他情况下,我可以看到正在调用R函数,但我找不到这些函数的源代码 > ts.union function (..., dframe = FALSE) .cbind.ts(list(...), .m
> t
function (x)
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>
在其他情况下,我可以看到正在调用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
如何找到.Primitive
函数的功能?类似地,有些函数调用.C
,.call
,.Fortran
,.External
或.Internal
。如何找到这些函数的源代码?UseMethod(“t”)
告诉您,t()
是一个()泛型函数,具有用于不同对象类的方法
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
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.
getMethod
可用于查看以下方法之一的源代码:
> getMethod("chol2inv", "diagonalMatrix")
Method Definition:
function (x, ...)
{
chk.s(...)
tcrossprod(solve(x))
}
<bytecode: 0x000000000ea2cc70>
<environment: namespace:Matrix>
Signatures:
x
target "diagonalMatrix"
defined "diagonalMatrix"
要查看这些方法之一的源代码,必须提供完整的签名,例如
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
和makenamets
是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>
这将下载Matrix软件包的源版本,并将相应的.tar.gz
文件保存在当前目录中。编译函数的源代码可以在未压缩和未编译文件的src
目录中找到。解压和解压步骤可以在R
之外完成,也可以使用untar()
功能从R
内部完成。可以将下载和扩展步骤合并到单个调用中(注意,一次只能下载和解包一个包):
或者,如果包开发是公开托管的(例如,通过或),您可能可以在线浏览源代码
基本包中的编译代码
某些包被视为“基本”包。这些包随R一起提供,其版本锁定为R的版本。示例包括base
、compiler
、stats
和utils
。因此,如上所述,它们不能在CRAN上作为单独的可下载包提供。相反,它们是/src/library/
下各个包目录中R源代码树的一部分。下一节将介绍如何访问R源
编译后的代码内置于R解释器中
如果您想查看R解释器内置的代码,则需要下载/解包R源代码;或者您可以通过R或在线查看来源
Uwe-Ligges(第43页)是一个很好的关于如何查看
.Internal
和.Primitive
函数源代码的一般参考。基本步骤是首先在src/main/names.c
中查找函数名,然后在src/main/*
中的文件中搜索“c条目”名,以及关于此问题的其他答案及其副本,下面是一种获取包函数源代码的好方法,无需知道它在哪个包中。
e、 g.说如果我们想要随机森林::rfcv()的源代码:
要在弹出窗口中查看/编辑它,请执行以下操作:
请注意,edit()
打开一个文本编辑器(由用户选择),而
View()
调用电子表格样式的数据查看器
View()
- 因此,当只想查看代码时,
edit()
实际上比view()
好得多,因为使用edit()
可以折叠/隐藏/伪造所有参数解析/检查/默认/错误消息逻辑,这些逻辑可能占R函数的70%,只需进入函数实际执行操作的部分(!),返回类型是什么类型的对象,是否递归以及如何递归,等等
重定向到一个单独的文件(这样你就可以在你喜欢的IDE/编辑器中打开代码/用grep/等处理代码):
当您使用debug()函数进行调试时,它会显示出来。
假设您希望在t()转置函数中看到底层代码。仅仅输入“t”并不能透露太多信息
>t
function (x)
UseMethod("t")
<bytecode: 0x000000003085c010>
<environment: namespace:base>
>t
功能(x)
使用方法(“t”)
但是,使用“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") <- NULL
Browse[3]>
debug: t(x)
调试(t)
>t(二氧化碳)
调试时间:t(co2)
调试:使用方法(“t”)
浏览[2]>
调试时间:t.ts(co2)
调试:{
cl在R编辑中有一个非常方便的功能
new_optim <- edit(optim)
显然,这不能用于查看C/C++或Fortran源代码
顺便说一句,edit
可以打开列表、矩阵等其他对象,然后显示带有属性的数据结构。Functionde
可以用于打开类似excel的编辑器(如果GUI支持)修改矩阵或数据框并返回新的矩阵或数据框。这有时很方便,但在通常情况下应该避免,尤其是当矩阵很大时。没有看到这与主要答案的流程有什么关系,但它让我困惑了一段时间,因此我在这里添加它:
中缀运算符
要查看某些基本中缀运算符的源代码(例如,%%
,%%*%%
,%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("%%")
主要答案包括如何使用镜像进行深入挖掘。对于非基本函数,R base包含一个名为body()的函数<
> 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>
download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")
untar(download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")[,2])
edit(getAnywhere('rfcv'), file='source_rfcv.r')
View(getAnywhere('rfcv'), file='source_rfcv.r')
capture.output(getAnywhere('rfcv'), file='source_rfcv.r')
>t
function (x)
UseMethod("t")
<bytecode: 0x000000003085c010>
<environment: namespace:base>
> 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") <- NULL
Browse[3]>
debug: t(x)
new_optim <- edit(optim)
invisible(edit(optim))
getAnywhere("%%")
# A single object matching ‘%%’ was found
# It was found in the following places
# package:base
# namespace:base
# with value
#
# function (e1, e2) .Primitive("%%")
body(print.Date)
{
if (is.null(max))
max <- getOption("max.print", 9999L)
if (max < length(x)) {
print(format(x[seq_len(max)]), max = max, ...)
cat(" [ reached getOption(\"max.print\") -- omitted",
length(x) - max, "entries ]\n")
}
else print(format(x), max = max, ...)
invisible(x)
}
capture.output(print(body(print.Date)))
[1] "{"
[2] " if (is.null(max)) "
[3] " max <- getOption(\"max.print\", 9999L)"
[4] " if (max < length(x)) {"
[5] " print(format(x[seq_len(max)]), max = max, ...)"
[6] " cat(\" [ reached getOption(\\\"max.print\\\") -- omitted\", "
[7] " length(x) - max, \"entries ]\\n\")"
[8] " }"
[9] " else print(format(x), max = max, ...)"
[10] " invisible(x)"
[11] "}"
sourceVector = capture.output(print(body(x[["fun"]])))
cat(paste0(" ", sourceVector, "\n"))
sourceVector = deparse(body(x$fun))
> functionBody(functionName)