I want to review the use of na.rm in the base packages initially, but the general idea would be to find any parameter in any packages.
Packages
packages = (.packages());
Functions in Packages
I don't know how reliable this is, as it was later throwing errors on formals
# https://stackoverflow.com/questions/8696158/find-all-functions-including-private-in-a-package
functions.listFromPackage = function(pkg = "stats")
{
all = ls( getNamespace(pkg), all.names = TRUE);
# public has to be loaded ...
public = ls( paste0("package:", pkg), all.names = TRUE);
private = setdiff(all, public);
list("public" = public, "private" = private);
}
Formals
Since the list above gives me strings, I guess I have to parse so formals will like the input.
has.na = NULL;
## LOOP over fn.str in package
fn.obj = eval(parse(text=fn.str));
x = formals( fn.obj );
if(is.primitive(fn.obj)) { x = formals(args(fn.obj)); }
if("na.rm" %in% names(x) )
{
row = c(package, fn, x$na.rm);
has.na = rbind(has.na, row);
}
Preliminary Results
> has.na
[,1] [,2] [,3]
row "stats" "approx" "TRUE"
row "stats" "approxfun" "TRUE"
row "stats" "density.default" "FALSE"
row "stats" "fivenum" "TRUE"
row "stats" "heatmap" "TRUE"
row "stats" "IQR" "FALSE"
row "stats" "mad" "FALSE"
row "stats" "median" "FALSE"
row "stats" "median.default" "FALSE"
row "stats" "medpolish" "FALSE"
row "stats" "sd" "FALSE"
row "stats" "var" "FALSE"
row "methods" "Summary" "FALSE"
row "base" ".colMeans" "FALSE"
row "base" ".colSums" "FALSE"
row "base" ".rowMeans" "FALSE"
row "base" ".rowSums" "FALSE"
row "base" "all" "FALSE"
row "base" "any" "FALSE"
It is throwing a lot of errors.
Warning messages:
1: In formals(fun) : argument is not a function
# for example fn.str = "p.adjust.methods"
Error in get(fun, mode = "function", envir = envir) :
first argument has length > 1
# for example fn.str = "contrasts<-"
Error in parse(text = fn) : <text>:2:0: unexpected end of input
1: contrasts<-
# obvious why `eval` fails here. How to get the formals in a variadic way (as a list of strings?)
So I am thinking my collection of functions may be inaccurate?
Question: how to write a function that captures all functions that use a parameter (with the default value) for a given set of package(s)?
==Accepted Solution==
The match.fun() was the key element of the solution. I have my function loop over the GLOBAL ls(all.names=TRUE) for local functions, then I loop over a list of packages specified in the package call.
Here is the head/str of one result:
> head(df)
pkg fn.is fn.name param.value
row stats public approx TRUE
row.1 stats public approxfun TRUE
row.2 stats public density.default FALSE
row.3 stats public fivenum TRUE
row.4 stats public heatmap TRUE
row.5 stats public IQR FALSE
> str(df)
'data.frame': 44 obs. of 4 variables:
$ pkg : chr "stats" "stats" "stats" "stats" ...
$ fn.is : chr "public" "public" "public" "public" ...
$ fn.name : chr "approx" "approxfun" "density.default" "fivenum" ...
$ param.value: chr "TRUE" "TRUE" "FALSE" "TRUE" ...
- attr(*, "param")= chr "na.rm"
- attr(*, "packages")= chr [1:2] "stats" "base"
>
I intentionally did NOT cast to anything on the dataframe. The na.rm example has unique: TRUE, FALSE, "" (listed as a function parameter without any default assigned). Post processing on the function can create factors and so on.
TODO: allow for the parameter to be a vector, maybe JSON.stringify using jsonlite::FUNCTIONS