How to list all the functions signatures in an R file?
UPDATE: Please refer to the answer by @Konrad Rudolph instead
You can create a new environment, source your file in that environment and then list the functions in it using lsf.str() e.g.
test.env <- new.env()
sys.source("myfile.R", envir = test.env)
lsf.str(envir=test.env)
rm(test.env)
or if you want to wrap it as a function:
listFunctions <- function(filename) {
temp.env <- new.env()
sys.source(filename, envir = temp.env)
functions <- lsf.str(envir=temp.env)
rm(temp.env)
return(functions)
}
How to find all functions in an R package?
I am guessing that you are just looking for help(package = caTools)
, which will open your browser to the relevant help page that lists all the functions in the "caTools" package.
You can also try: library(help = caTools)
, but that doesn't seem to capture everything. The nice thing about this latter approach is that you can capture the output in case you needed to refer to it somewhere else:
x <- library(help = caTools)
x$info[[2]]
# [1] "LogitBoost LogitBoost Classification Algorithm"
# [2] "base64encode Convert R vectors to/from the Base64 format"
# [3] "caTools-package Tools: moving window statistics, GIF, Base64,"
# [4] " ROC AUC, etc."
# [5] "colAUC Column-wise Area Under ROC Curve (AUC)"
# [6] "combs All Combinations of k Elements from Vector v"
# [7] "predict.LogitBoost Prediction Based on LogitBoost Classification"
# [8] " Algorithm"
# [9] "read.ENVI Read and Write Binary Data in ENVI Format"
# [10] "read.gif Read and Write Images in GIF format"
# [11] "runmad Median Absolute Deviation of Moving Windows"
# [12] "runmean Mean of a Moving Window"
# [13] "runmin Minimum and Maximum of Moving Windows"
# [14] "runquantile Quantile of Moving Window"
# [15] "runsd Standard Deviation of Moving Windows"
# [16] "sample.split Split Data into Test and Train Set"
# [17] "sumexact Basic Sum Operations without Round-off Errors"
# [18] "trapz Trapezoid Rule Numerical Integration"
find all functions (including private) in a package
you can use asNamespace
:
> methods(cbind)
[1] cbind.data.frame cbind.grobGrid cbind.ts*
Non-visible functions are asterisked
> r <- unclass(lsf.str(envir = asNamespace("stats"), all = T))
> r[grep("cbind.ts", r)]
[1] ".cbind.ts" "cbind.ts"
cbind.ts
in stats
package is invisible but can find in envir = asNamespace("stats")
.
How to print signatures of all functions/methods in a Python project?
You can tokenize the file and use that to print function definitions:
import token
from tokenize import generate_tokens
def find_definitions(filename):
with open(filename) as f:
gen = generate_tokens(f.readline)
for tok in gen:
if tok[0] == token.NAME and tok[1] == 'def':
# function definition, read until next colon.
definition, last_line = [tok[-1]], tok[3][0]
while not (tok[0] == token.OP and tok[1] == ':'):
if last_line != tok[3][0]:
# more than one line, append, track line number
definition.append(tok[-1])
last_line = tok[3][0]
tok = next(gen)
if last_line != tok[3][0]:
definition.append(tok[-1])
yield ''.join(definition)
This works regardless of how many lines a function definition uses.
Demo:
>>> import textwrap
>>> gen = find_definitions(textwrap.__file__.rstrip('c'))
>>> for definition in gen:
... print(definition.rstrip())
...
def __init__(self,
width=70,
initial_indent="",
subsequent_indent="",
expand_tabs=True,
replace_whitespace=True,
fix_sentence_endings=False,
break_long_words=True,
drop_whitespace=True,
break_on_hyphens=True):
def _munge_whitespace(self, text):
def _split(self, text):
def _fix_sentence_endings(self, chunks):
def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
def _wrap_chunks(self, chunks):
def wrap(self, text):
def fill(self, text):
def wrap(text, width=70, **kwargs):
def fill(text, width=70, **kwargs):
def dedent(text):
The above uses the textwrap
module to demonstrate how it can handle multi-line definitions.
If you need to support Python 3 code with annotations, you'll need to be a little bit cleverer and track open and closing parens too; a colon within the parentheses doesn't count. On the other hand, Python 3 tokenize.tokenize()
produces named tuples which make the function below a little easier to read:
import token
from tokenize import tokenize
def find_definitions(filename):
with open(filename, 'rb') as f:
gen = tokenize(f.readline)
for tok in gen:
if tok.type == token.NAME and tok.string == 'def':
# function definition, read until next colon outside
# parentheses.
definition, last_line = [tok.line], tok.end[0]
parens = 0
while tok.exact_type != token.COLON or parens > 0:
if last_line != tok.end[0]:
definition.append(tok.line)
last_line = tok.end[0]
if tok.exact_type == token.LPAR:
parens += 1
elif tok.exact_type == token.RPAR:
parens -= 1
tok = next(gen)
if last_line != tok.end[0]:
definition.append(tok.line)
yield ''.join(definition)
In Python 3 you'd preferably open source files in binary mode and let the tokenizer figure out the right encoding. Also, the above Python 3 version can tokenize Python 2 code without issue.
How can I view the source code for a function?
UseMethod("t")
is telling you that t()
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.
> 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 (i.e. stats:::t.ts
), or by using getAnywhere()
. getAnywhere()
is useful because you don't have to know which package the function came from.
> 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>
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:
> 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.
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:
> 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("chol2inv", "diagonalMatrix")
Method Definition:
function (x, ...)
{
chk.s(...)
tcrossprod(solve(x))
}
<bytecode: 0x000000000ea2cc70>
<environment: namespace:Matrix>
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, e.g.
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. You can view the source code of unexported functions by using the :::
operator or 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>
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 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. 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's C_optimhess
, not "C_optimhess"
). optim
is in the stats package, so you can type stats:::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.
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. Source code for compiled functions can be found in the src
directory of the uncompressed and untared file. The uncompressing and untaring step can be done outside of R
, or from within R
using the untar()
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):
untar(download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")[,2])
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
, and utils
. 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 in src/main/names.c
and then search for the "C-entry" name in the files in src/main/*
.
Related Topics
Drawing a Stratified Sample in R
Using Rvest to Scrape a Website W/ a Login Page
R Shiny - Uioutput Not Rendering Inside Menuitem
How to Convert a Character String Date to Date Class If Day Value Is Missing
Avoid Ggplot2 to Partially Cut Axis Text
Ggplot2: More Complex Faceting
Categorical Scatter Plot with Mean Segments Using Ggplot2 in R
How to Optimize the Following Code with Nested While-Loop? Multicore an Option
What If I Want to Web Scrape with R for a Page with Parameters
Separate a Column into 2 Columns at the Last Underscore in R
Installing "Rgl" Package in R, MAC Osx El Captian
Difference Between Backticks and Quotes in Aes Function in Ggplot
Are Factors Stored More Efficiently in Data.Table Than Characters
Subset() a Factor by Its Number of Observation
Convert Data Frame Common Rows to Columns
Error in Chol.Default(Cxx):The Leading Minor of Order Is Not Positive Definite