How can you find the names and locations of all the functions that have a specific argument? Is there a way to find them for functions in the global environment, attached packages, and installed packages?
I assume that you ask the question just to not lose Ben great answer.
Here I slightly modify Ben answer to search for any argument :
uses_arg <- function(x,arg)
is.function(fx <- get(x)) &&
arg %in% names(formals(fx))
For example to get function with na.rm argument :
basevals <- ls(pos="package:base") ## package name : here I use the base package
basevals[sapply(basevals,uses_arg,'na.rm')]
EDIT
better to name argument of ls in conjunction with asNamespace :
basevals <- ls(asNamespace('base'))
basevals[sapply(basevals,uses_arg,'na.rm')]
Related
I am running a simple R program that I have recently written in the last month. I used to be able to call R functions from it. I am calling lucas_Lehmer2 right now ...
two <- as.bigz(2)
merNums <- two^p-1
t1 <- lucas_Lehmer2(p,merNums)
mP <- merNums[t1]
When I run the calling R script I get:
Error in lucas_Lehmer2(p, merNums) :
could not find function "lucas_Lehmer2"
I have set the working directory correctly too. I checked that the function name matched the filename too. Does anyone have any ideas?
I couldn't find it on CRAN. Since you've had it recently (and have not updated or reloaded-completely or started-from-scratch your R), then here's a trick that may find it for you.
I don't have that function, so I'll look for one that I know I have: a function that includes roxygen in the function name. (While we know where that is, we'll go through the steps to confirm it.
pkgs <- list.files(.libPaths()[1], pattern = "^NAMESPACE$", recursive = TRUE, full.names = TRUE)
names(pkgs) <- basename(dirname(pkgs))
ptn <- "\\(.*roxygen.*\\)" # you should use lucas_Lehmer
ret <- lapply(pkgs, function(fn) grep(ptn, readLines(fn), value = TRUE))
ret <- ret[lengths(ret) > 0]
str(ret)
# List of 2
# $ roxygen2: chr [1:3] "export(roxygenise)" "export(roxygenize)" "useDynLib(roxygen2, .registration=TRUE)"
# $ usethis : chr "export(use_roxygen_md)"
In this case, there are two packages installed in my instance of R-4 that have functions that contain roxygen.
For my search, since many many many packages have a header row that says "# Generated by roxygen2: do not edit by hand", so I had to make my search a little more specific to include surrounding parens. One could make this search significantly more specific or general. In your case, I think finding anything with lucas_Lehmer might be sufficient, no need for regex fanciness.
This trick will work only if it is in your .libPaths()[1]. For most installations, this is where non-standard packages are installed, but your case might be different. If that is true, then iterate over each path within .libPaths() until you find something. If none of these work, perhaps look in library paths for older versions of R. For instance, if you recently upgraded to R-4.0, then your .libPaths() entry likely includes "4.0" somewhere in the path; look for a neighboring older-version directory and look there until you find the specific package. Once you find it in an older-version-package, then you'll need to install.packages it into R-4.
Hope this helps.
I want to acquire the list of functions, defined in the package and exported, but not the ones that were imported from other packages?
The following solutions are nice, but list also function re-exported:
Seeking Functions in a Package
getNamespaceExports() is mentioned in one of the answers to the question you linked; luckily, there is a companion to it, getNamespaceImports(). Then we can just find the setdiff() between the two. For example:
devtools_exports <- getNamespaceExports("devtools")
devtools_imports <- getNamespaceImports("devtools")
devtools_exported_not_imported <- setdiff(devtools_exports, devtools_imports)
"install_github" %in% devtools_exports
# [1] TRUE
"install_github" %in% devtools_exported_not_imported # comes from remotes
# [1] FALSE
Actually, I found one more solution that seems to work well:
unclass(lsf.str(envir = asNamespace('myPackage')))
The benefit is that I don't get these system variables:
"system.file" "library.dynam.unload" ".__global__"
I like using function reshape from the matlab package, but I need then to specify base::sum(m) each time I want to sum the elements of my matrix or else matlab::sum is called, which only sums by columns..
I need loading package gtools to use the rdirichlet function, but then the function gtools::logit masks the function pracma::logit that I like better..
I gess there are no such things like:
library(loadOnly = "rdirichlet", from = "gtools")
or
library(loadEverythingFrom = "matlab", except = "sum")
.. because functions from the package matlab may internaly work on the matlab::sum function. So the latter must be loaded. But is there no way to get this behavior from the point of view of the user? Something that would feel like:
library(pracma)
library(matlab)
library(gtools)
sum <- base::sum
logit <- pracma::logit
.. but that would not spoil your ls() with all these small utilitary functions?
Maybe I need defining my own default namespace?
To avoid spoiling your ls, you can do something like this:
.ns <- new.env()
.ns$sum <- base::sum
.ns$logit <- pracma::logit
attach(.ns)
To my knowledge there is no easy answer to what you want to achieve. The only dirty hack I can think of is to download the source of the packages "matlab", "gtools", "pracma" and delete the offending functions from their NAMESPACE file prior to installation from source (with R CMD INSTALL package).
However, I would recommend using the explicit notation pracma::logit, because it improves readability of your code for other people and yourself in the future.
This site gives a good overview about package namespaces:
http://r-pkgs.had.co.nz/namespace.html
I was trying to acquaint myself with R's nChooseK function but I can't get it to work. I thought it was part of the standard setup (i.e. no additional package needed).
Please help. Here is what I tried:
> nChooseK(10,2)
Error: could not find function "nChooseK"
> n<-4;k<-2
> print(nChooseK(n,k))
Error in print(nChooseK(n, k)) : could not find function "nChooseK"
the last one was an example I saw here: R basic nChooseK
The function is in the R.basic package which is not part of the default R installation. You probably meant to use just choose().
As joran mentions the function nChooseK is a part of R.basic. You can tell this from the example you posted by looking at the top of the page:
You'll notice the "R.basic" in the curley braces which tells you that that function is a part of the "R.basic" package. So to use nChooseK you'll first need to load that package
library(R.basic)
If you don't have R.basic installed yet then you'll need to install it
install.packages("R.basic", contriburl="http://www.braju.com/R/repos/")
library(R.basic)
But as noted the choose function in base R does the same thing
choose(37, 12)
#[1] 1852482996
nChooseK(37, 12)
#[1] 1852482996
If I need to use a data set inside a function (as a lookup table) inside of a package I'm creating do I need to explicitly load the data set inside of the function?
The function and the data set are both part of my package.
Is this the correct way to use that data set inside the function:
foo <- function(x){
x <- dataset_in_question
}
or is this better:
foo <- function(x){
x <- data(dataset_in_question)
}
or is there some approach I'm not thinking of that's correct?
There was a recent discussion about this topic (in the context of package development) on R-devel, numerous points of which are relevant to this question:
If only the options you provide are applicable to your example R himself (i.e., Brian Ripley) tells you to do:
foo <- function(x){
data("dataset_in_question")
}
This approach will however throw a NOTE in R CMD check which can be avoided in upcoming versions of R (or currently R devel) by using the globalVariables() function, added by John Chambers
The 'correct' approach (i.e., the one advocated by Brian Ripley and Peter Dalgaard) would be to use the LazyData option for your package. See this section of "Writing R Extensions".
Btw: I do not fully understand how your first approach should work. What should x <- dataset_in_question do? Is dataset_in_question a global Variable or defined previously?
For me it was necessary to use get() additionally to LazyData: true in DESCRIPTION file (see postig by #Henrik point 3) to get rid of the NOTE no visible binding for global variable .... My R version is 3.2.3.
foo <- function(x){
get("dataset_in_question")
}
So LazyData makes dataset_in_question directly accessible (without using data("dataset_in_question", envir = environment())) and get() is to satisfy R CMD check
HTH
One can just place the data set as a .rda file in the R folder as described by Hadley here: http://r-pkgs.had.co.nz/data.html#data-sysdata
Matthew Jockers uses this approach in the syuzhet package for data sets including the bing data set as seen at ~line 452 here: https://github.com/mjockers/syuzhet/blob/master/R/syuzhet.R
bing is not available to the user but is to the package as demonstrated by: syuzhet:::bing
Essentially, the command devtools::use_data(..., internal = TRUE) will set everything up in the way it's needed.