Skip to content

listing all functions in R

12 messages · Brian Ripley, Gavin Simpson, Duncan Murdoch +5 more

#
Dear List,

I'm building an R syntax highlighting file for GeSHi [*] for a website I
am currently putting together. The syntax file needs a list of keywords
to highlight. How can I generate a list of all the functions in a base R
installation?

Ideally the list would be formatted like this:

"'fun1', 'fun2', 'fun3'" 

when printed to the screen so I can copy and paste it into the syntax
file.

I'm sure this has been asked before, but I stupidly didn't save that
email and I couldn't come up with a suitable query parameter for
Jonathan Baron's search site to return results before timing out.

Thanks in advance,

Gav
#
Could you tell us what you mean by

- 'function'  (if() and + are functions in R, so do you want those?)

- 'a base R installation'?   What is 'base R' (standard + recommended 
packages?)  And on what platform: the list is platform-specific?

Here is a reasonable shot:

findfuns <- function(x) {
     if(require(x, character.only=TRUE)) {
        env <- paste("package", x, sep=":")
        nm <- ls(env, all=TRUE)
        nm[unlist(lapply(nm, function(n) exists(n, where=env,
                                               mode="function",
                                               inherits=FALSE)))]
     } else character(0)
}
pkgs <- dir(.Library)
z <-  lapply(pkgs, findfuns)
names(z) <- pkgs

I don't understand your desired format, but

write(sQuote(sort(unique(unlist(z)))), "")

gives a single-column quoted list.  It does include internal functions, 
operators, S3 methods ... so you probably want to edit it.
On Sat, 6 Jan 2007, Gavin Simpson wrote:

            

  
    
#
On Sat, 2007-01-06 at 13:48 +0000, Prof Brian Ripley wrote:
Thank you for your reply, Prof. Ripley.
I was thinking about functions that are used like this: foo()
So I don't need things like "names<-". I don't need functions like +. -,
$, as I can highlight the separately if desired, though I'm not doing
this at the moment.

Functions like for() while(), if() function() are handled separately.
Yes, I mean standard + recommended packages. As for platform, most of my
intended audience will be MS Windows users, though I am using Linux
(Fedora) to generate this list (i.e. my R installation is on Linux).
Excellent, that works just fine for me. I can edit out certain packages
that I don't expect to use, before formatting as desired. I can also use
this function on a library of packages that I use regularly and will be
using in the web pages.
I wanted a single string "...", with entries enclosed in "''" and
separated by "," (this is to go in a PHP array). I can generate such a
string from your z, above, as follows:

paste(sQuote(sort(unique(unlist(z)), decreasing = TRUE)), 
      collapse = ", ")
Once again, thank you.

All the best

Gav
#
On 1/6/2007 9:25 AM, Gavin Simpson wrote:
Be careful:  the installed list of functions differs slightly from 
platform to platform.  For example, on Windows there's a function 
choose.dir in the utils package, but I don't think this exists on Unix.

The list also varies from version to version, so if you could manage to 
run some code in the user's installed R to generate the list on the fly, 
you'd get the most accurate list.

Duncan Murdoch
#
The arguments to the functions can differ too even if they
exist on multiple platforms.   system() on Windows has the
input= argument but not on UNIX.
On 1/6/07, Duncan Murdoch <murdoch at stats.uwo.ca> wrote:
#
On Sat, 2007-01-06 at 10:43 -0500, Duncan Murdoch wrote:
Cheers Duncan.
Good point. However as I am in control of the R snippets I display on
the web pages and the highlighting file/list, I can add the odd thing
that Brian Ripley's findfuns function doesn't list because of platform
differences.

What I wanted to avoid was having to add functions to my key word list
each time I wrote another page on the site that used a new R snippet. As
it is early days, I'd probably spend about as much time adding functions
to the keyword list as writing pages for the site - which would put me
of a bit and slow me down. At least now I only have to add the odd
function missed.
Yes. I'm planning on wrapping findfuns into a little R script that
searches additional packages that I'll use, and that will update the
packages before compiling the list. I can then run this script
periodically in R to update the list, as R is updated etc.
Many thanks for your reply,

All the best,

G
#
On Sat, 2007-01-06 at 10:58 -0500, Gabor Grothendieck wrote:
That's a good point Gabor, and one I hadn't considered as yet. As I'm
only just setting out on the road to providing R help resources for the
wider world (rather than the limited environs of the courses I have
run), I tend to not have thought about these things much - though I
guess I have a few gotchas waiting to bite me in the ass before too
long.

I am just starting to think about the best way to organise the snippets
of code to allow me to keep them up-to-date with current R and changes
in package code that the snippets use. Dropping the code verbatim into
PHP scripts isn't a good idea. At the moment I intend to store all
snippets in individual *.R files and read them into to variables within
the PHP scripts, from where they will be highlighted and formatted for
display.

It would be reasonably easy to write an R script to source all *.R files
in a directory to look for errors and problems. And having them all as
separate files means I can still use Emacs/ESS to prepare, format, and
run the code through R, which is my preferred environment.

All the best,

G
2 days later
#
"Prof Brian Ripley" <ripley at stats.ox.ac.uk> wrote in message 
news:Pine.LNX.4.64.0701061331420.8651 at gannet.stats.ox.ac.uk...
Any recommendations on how to trap problems with "require" when using 
findfuns?  One bad package and the lapply above doesn't return anything.

For example:
Loading required package: bcp
Loading required package: DNAcopy
Error: package 'DNAcopy' could not be loaded
In addition: Warning message:
there is no package called 'DNAcopy' in: library(pkg, character.only = TRUE, 
logical = TRUE, lib.loc = lib.loc)
Loading required package: bcp
Loading required package: DNAcopy
Error: package 'DNAcopy' could not be loaded
In addition: Warning message:
there is no package called 'DNAcopy' in: library(pkg, character.only = TRUE, 
logical = TRUE, lib.loc = lib.loc)


I used "try" around the "require" call with "options(error=recover)" with 
"recover" defined to be a do nothing function to avoid the stop, but then 
there were other problems (e.g., "unable to load shared library ... 
LoadLibrary Failure: The specified module could not be found" and "Maximal 
number of DLLs reached")

Besides "bcp" I saw problems with other packages, e.g., cairoDevice, 
caMassClass, ... several others.

I'm using R 2.4.1with all CRAN packages installed that existed last week and 
at least several Bioconductor packages installed by the biocLite procedure.

FWIW:
[1] 957


Thanks for any suggestions.

efg

Earl F. Glynn
Scientific Programmer
Stower Institute
#
"Earl F. Glynn" <efg at stowers-institute.org> writes:
Are you sure you need to?  I just tried your code above with:

pkgs <- c("Biobase", "GOstats", "flrblr", "bazbaz")

And while I see warning messages about the flrblr and bazbaz packages,
the function completed and I get the expected results in z.

Oh, perhaps you have some broken installs?  Broken in the sense that
you have a package installed but not its dependencies?

How about this:

safeRequire <- function(x) {
    tryCatch(require(x, character.only=TRUE),
             error=function(e) FALSE)
}

And then replace the call to require in findfuns().

+ seth
#
"Seth Falcon" <sfalcon at fhcrc.org> wrote in message 
news:m23b6k5idc.fsf at fhcrc.org...
I installed all known CRAN packages after installing R 2.4.1 last week on a 
PC.  Perhaps some new consistency checks checks could be be made to catch 
such dependency problems?
Thanks.  That's a much better function.

But if your process a lot of packages, even with just safeRequire (or 
findfuns), the search() path grows quite long, and things break, so it's not 
really possible to get a list of all functions in R if you have all packages 
installed.

Consider:

pkgs <- dir(.Library)

length(pkgs)        #957

length( search() )  # 9

# First 100 Packages
set1 <- lapply(pkgs[1:100], safeRequire)
pkgs[which(!unlist(set1))]
#[1] "bcp"         "cairoDevice" "caMassClass"
length( search() )  # 135

safeRequire("bcp")

####################################
Loading required package: bcp
Loading required package: DNAcopy
Warning in library(pkg, character.only = TRUE, logical = TRUE, lib.loc = 
lib.loc) :
         there is no package called 'DNAcopy'
[1] FALSE
####################################


In the 2nd 100 many packages seem to be affected by the "Maximal number of 
DLLs reached..."

I didn't bother trying to process packages 201 through 957.

efg

Earl F. Glynn
Scientific Programmer
Bioinformatics
Stowers Institute for Medical Research
5 days later
#
Hello,

First, regarding GeSHi syntax highlighting for R, I have done one for
the R Wiki (plus the R function that generates the list of keywords
automatically). I will attach it to a second email send privately to
you, since the mailing list do not accept attachments.

For the problem of keeping web pages up-to-date with R code, I am also
considering this problem with the R Wiki. Although I still do not have a
completely working solution, the approach is similar to Sweave. I have a
function which extracts the R code from wiki pages (that is, it
'Stangles' the wiki page, in the Sweave terminology). I can get, thus,
the R code from all wiki pages in turn, test them and write a report
with a couple of R code lines. Here is are my functions:

getWikiRcode <- function(wikipage, url = "http://wiki.r-project.org/rwiki",
	strip.empty.lines = TRUE, strip.output = FALSE) {
	# Read the raw wiki page
	Url <- paste(url, "/doku.php?id=", wikipage, "&do=export_raw", sep ="")
	Raw <- readLines(Url)
	
	# Get only <code r> .... </code> chunks from this page
	Codestart <- grep("^\\s*<code", Raw)
	Codeend <- grep("^\\s*</code>", Raw)
	# A little bit of checking first
	if (length(Codestart) != length(Codeend) || any(Codeend <= Codestart))
		stop("Malformed wiki page (wrong <code>... </code> sections)")	
	# Get only r code sections (those starting with <code r> from the list
	Rstart <- grep("^\\s*<code r>", Raw)
	if (length(Rstart) == 0) return(character(0))	# no R code in this page
	isRsection <- Codestart %in% Rstart
	Rend <- Codeend[isRsection]
	
	# Construct the list of text lines related to r code
	R <- data.frame(Start = Rstart, End = Rend)
	Seq <- function(x) seq(from = x[1], to = x[2])
	Rrows <- c(apply(R, 1, Seq), recursive = TRUE)
	Rcode <- Raw[Rrows]
	
	# Eliminate <code r> and </code> tags
	Rcode <- gsub("^\\s*</?code( r)?>.*$", "", Rcode)
	
	# Eliminate prompt from R code '> ', or '+ ' at the begining of a line
	Rcode <- sub("^[>+] ", "", Rcode)
	
	# Possibly eliminate empty lines
	if (strip.empty.lines) Rcode <- Rcode[Rcode != ""]
	
	# Possibly eliminate output (lines starting with '#!')
	if (strip.output) {
		Routput <- grep("^\\#\\!", Rcode)
		if (length(Routput) > 0) Rcode <- Rcode[-Routput]
	}
	
	# Return the R code
	return(Rcode)
}

rcode <- getWikiRcode("tips:data-frames:merge")
rcode

sourceWikiRcode <- function(wikipage, echo = TRUE, url =
"http://wiki.r-project.org/rwiki",
	strip.empty.lines = TRUE, strip.output = FALSE, ...) {
	# Call getWikiRcode() to extract r code from wiki pages
	Rcode <- getWikiRcode(wikipage = wikipage, url = url,
		strip.empty.lines = strip.empty.lines, strip.output = strip.output)
	if (length(Rcode) == 0) {
		warning("No r code in this page!")
	} else {
		Con <- textConnection(Rcode)
		source(Con, echo = echo, ...)
		close(Con)
	}
}

sourceWikiRcode("tips:data-frames:merge")
# Here, the last part of this page is not directly executable (data1 is
not defined)
# but the rest is fine!

This is suboptimal, and I am considering rewriting it in PHP to return R
code only from the wiki server.

Best,

Philippe Grosjean
Gavin Simpson wrote:
#
PhGr> ............
    PhGr> I will attach it to a second email send privately to
    PhGr> you, since the mailing list do not accept attachments.

That's not correct.
http://www.r-project.org/mail.html  (search for "attachment")
explains that most ** binary ** attachments are not accepted,
lists the exceptions and further says that  
text/plain is well accepted
(BTW,  text/html is accepted too, but translated to text/plain
 by the filters)

One problem is that many e-mail client programs do not seem to
let you attach "text/plain" easily.

Martin