How to get the package name of a function in R?
Perhaps even most convenient, if you are just after the package name:
environmentName(environment(select))
The advantage is that this produces a string rather than an environment object.
Name of a package for a given function in R
There may be better solutions, but find("functionname")
seems to work reasonably well? However, it only works for loaded packages.
> find("strwidth")
[1] "package:graphics"
> find("qplot")
character(0)
> library(ggplot2)
> find("qplot")
[1] "package:ggplot2"
>
(If you need the raw name of the package you can use gsub("^package:","",results)
)
(The answers to the previous question linked by Andrie include this answer; they don't give the bit about gsub
, and they all seem to share the issue of not finding non-loaded packages.)
Here's a quick hack to find functions even in non-loaded packages:
findAllFun <- function(f) {
h <- help.search(paste0("^",f,"$"),agrep=FALSE)
h$matches[,"Package"]
}
findAllFun("qplot")
## "ggplot2"
findAllFun("lambertW")
## "emdbook" "VGAM"
> findAllFun("xYplot")
## "Hmisc" "lattice"
If you need to find functions in non-installed packages (i.e. searching CRAN), then findFn
from the sos
package will be your friend.
Finding a function of a specific package in RStudio help pane
RStudio HelpPane
Today the RStudio java code for help Window (see -> HelpPane.java:364) does not support the ability to search a specific package context. It could but it would require modifications to HelpSearch.java:67
./rstudio/src/gwt/src/org/rstudio/studio/client/workbench/views/help
./HelpPane.java:364:
toolbar.addRightWidget(searchProvider_.get().getSearchWidget());
./search/HelpSearch.java:67:
public Widget getSearchWidget()
RStudio
Today, in RStudio you can do a help lookup via the R console and reflect the results in the RStudio help window. The workaround is to type ?dplyr::count
in the R Console and have this reflected in the RStudio help window.
I hope the above information if useful, and points you in the right direction. My sense is you'll need to request or change RStudio window behaviour.
R Help Observations:
If you wish to look up a specific function in a package you can use the following syntax:
help(count, package="dplyr")
Personally, I also recommend using the sos
library which adds ???
this enables access to the findfn()
and ???
which enables you to access RSiteSearch()
and search across all CRAN libraries for a function.
> require(sos)
>
> ???count
found 7174 matches; retrieving 20 pages, 400 matches.
2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
Downloaded 399 links in 244 packages.
The above syntax is referenced in the R documentation. https://www.r-project.org/help.html
R Help: help() and ?
The help()
function and ?
help operator in R provide access to the documentation pages for R functions, data sets, and other objects, both for packages in the standard R distribution and for contributed packages. To access documentation for the standard lm (linear model) function, for example, enter the command help(lm)
or help("lm")
, or ?lm
or ?"lm"
(i.e., the quotes are optional).
To access help for a function in a package that’s not currently loaded, specify in addition the name of the package: For example, to obtain documentation for the rlm()
(robust linear model) function in the MASS package, help(rlm, package="MASS")
.
Standard names in R consist of upper- and lower-case letters, numerals (0-9), underscores (_), and periods (.), and must begin with a letter or a period. To obtain help for an object with a non-standard name (such as the help operator ?), the name must be quoted: for example, help('?')
or ?"?"
.
You may also use the help() function to access information about a package in your library — for example, help(package="MASS")
— which displays an index of available help pages for the package along with some other information.
Help pages for functions usually include a section with executable examples illustrating how the functions work. You can execute these examples in the current R session via the example()
command: e.g., example(lm)
.
R - how to identify which version (package) of a function is active/attached?
You can find out which functions are in conflict (being masked) by using conflicts(detail = TRUE)
. This returns a named list of packages / functions in conflict in the order of the search()
path which is the order in which they will be called.
As an example, we can load dplyr
which loads some functions that conflict with base.
library(dplyr)
# Create data.frame of conflicts and clean up.
conf <- conflicts(detail = TRUE)
conf.df <- data.frame(do.call(rbind, Map(cbind, conf, names(conf))))
names(conf.df) <- c("fn", "package")
conf.df$package <- sub("package:", "", conf.df$package)
# Aggregate packages by function - first package is the default when called.
aggregate(package ~ fn, conf.df, toString)
fn package
1 body<- methods, base
2 filter dplyr, stats
3 intersect dplyr, base
4 kronecker methods, base
5 lag dplyr, stats
6 setdiff dplyr, base
7 setequal dplyr, base
8 union dplyr, base
R How to check that a custom function is called within a specific function from a certain package
Update: I'm going to "borrow" from rlang::trace_back
, since it seems to have an elegant (and working) method for determining a full package::function
for most of the call tree (some like %>%
are not always fully-resolved).
(If you're trying to reduce package bloat ... while it's unlikely you'd have dplyr
and not purrr
available, if you would prefer to do as much in base as possible, I've provided #==#
equivalent base-R calls. It's certainly feasible to try to remove some of the rlang
calls, but again ... if you're assuming dplyr
, then you definitely have rlang
around, in which case this should not be a problem.)
EDIT (2022-02-25): the function below uses
:::
functions inrlang
, which (not surprisingly) no longer exist as of today, as a clear example of why using:::
-funcs is inherently risky. This function no longer works. I'm not going to attempt to fix now (no immediate need/motivation). Cheers.
search_calling_pkg <- function(pkgs, funcs) {
# <borrowed from="rlang::trace_back">
frames <- sys.frames()
idx <- rlang:::trace_find_bottom(NULL, frames)
frames <- frames[idx]
parents <- sys.parents()[idx]
calls <- as.list(sys.calls()[idx])
calls <- purrr::map(calls, rlang:::call_fix_car)
#==# calls <- lapply(calls, rlang:::call_fix_car)
calls <- rlang:::add_pipe_pointer(calls, frames)
calls <- purrr::map2(calls, seq_along(calls), rlang:::maybe_add_namespace)
#==# calls <- Map(rlang:::maybe_add_namespace, calls, seq_along(calls))
# </borrowed>
calls_chr <- vapply(calls, function(cl) as.character(cl)[1], character(1))
ptn <- paste0("^(", paste(pkgs, collapse = "|"), ")::")
pkgres <- any(grepl(ptn, calls_chr))
funcres <- !missing(funcs) && any(mapply(grepl, paste0("^", funcs, "$"), list(calls_chr)))
if (!pkgres || !funcres) {
stop("not correct")
} else return()
}
The intention is that you can look for particular packages and/or particular functions. The funcs=
argument can be fixed strings (taken as verbatim), but since I thought you might want to match against any of the mutate*
functions (etc), you can also make it a regex. All functions need to be full package::funcname
, not just funcname
(though you could certainly make it a regex :-).
myfun1 <- function() {
search_calling_pkg(pkgs = "dplyr")
NULL
}
myfun2 <- function() {
search_calling_pkg(funcs = c("dplyr::mutate.*", "dplyr::summarize.*"))
NULL
}
mutate <- function(df, x) { force(x); NULL; }
mtcars[1:2,] %>% mutate(myfun1())
# Error: not correct
mtcars[1:2,] %>% dplyr::mutate(myfun1())
# mpg cyl disp hp drat wt qsec vs am gear carb
# 1 21 6 160 110 3.9 2.620 16.46 0 1 4 4
# 2 21 6 160 110 3.9 2.875 17.02 0 1 4 4
mtcars[1:2,] %>% mutate(myfun2())
# Error: not correct
mtcars[1:2,] %>% dplyr::mutate(myfun2())
# mpg cyl disp hp drat wt qsec vs am gear carb
# 1 21 6 160 110 3.9 2.620 16.46 0 1 4 4
# 2 21 6 160 110 3.9 2.875 17.02 0 1 4 4
And performance seems to be significantly better than the first answer, though still not a "zero hit" on performance:
microbenchmark::microbenchmark(
a = mtcars %>%
dplyr::mutate(),
b = mtcars %>%
dplyr::mutate(myfun1())
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# a 1.5965 1.7444 1.883837 1.82955 1.91655 3.0574 100
# b 3.4748 3.7335 4.187005 3.92580 4.18140 19.4343 100
(This portion kept for prosperity, though note that getAnywhere
will find dplyr::mutate
even if the above non-dplyr mutate
is defined and called.)
Seeded by Rui's links, I suggest that looking for specific functions might very well miss new functions and/or otherwise-valid but differently-named functions. (I don't have a clear example.) From here, consider looking for particular packages instead of particular functions.
search_calling_pkg <- function(pkgs) {
call_st <- lapply(sys.calls(), `[[`, 1)
res <- any(vapply(call_st, function(ca) any(pkgs %in% tryCatch(getAnywhere(as.character(ca)[1])$where, error=function(e) "")), logical(1)))
if (!res) {
stop("not called from packages")
} else return()
}
myfun <- function() {
search_calling_pkg("package:dplyr")
NULL
}
Realize that this is not an inexpensive operation. I believe the majority of time spent in this is dealing with the calling tree, perhaps not something we can easily remedy.
microbenchmark::microbenchmark(
a = mtcars %>% mutate(),
b = mtcars %>% mutate(myfun())
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# a 1.872101 2.165801 2.531046 2.312051 2.72835 4.861202 100
# b 546.916301 571.909551 603.528225 589.995251 612.20240 798.707300 100
If you believe it will be called infrequently and your function takes "a little time", then perhaps the half-second delay won't be that noticeable, but with this toy example the difference is palpable.
R: 2 functions with the same name in 2 different packages
You have probably already noticed that the order of loading the packages makes a difference, i.e. the package that gets loaded last will mask the functions in packages loaded earlier.
To specify the package that you want to use, the syntax is:
chron::is.weekend()
tseries::is.weekend()
In other words, use packagename::functionname()
In addition, if you know that you will always want to use the function in chron, you can define your own function as follows:
is.weekend <- chron::is.weekend #EDIT
R: Get function name called with package::function as string in R
I think substitute
could be your friend. From the docs:
substitute
returns the parse tree for the (unevaluated) expressionexpr
This allows you to access the (unevaluated) expression pack::foo
inside your function.
The following produces your desired outcome:
giveArgumentFunctionName <- function(func) {
function.name <- as.character(substitute(func))[[3]]
return (function.name)
}
giveArgumentFunctionName(pack::foo)
# [1] "foo"
giveArgumentFunctionName(pack::bar)
# [1] "bar"
Related Topics
Compute Projection/Hat Matrix via Qr Factorization, Svd (And Cholesky Factorization)
How to Prep Transaction Data into Basket for Arules
Manipulating Files with Non-English Names in R
Differencebetween Short (&,|) and Long (&&, ||) Forms of And, or Logical Operators in R
Blend of Na.Omit and Na.Pass Using Aggregate
Plot a Character Vector Against a Numeric Vector in R
How to Split Data Frame by Column Names in R
Can Sparklyr Be Used with Spark Deployed on Yarn-Managed Hadoop Cluster
Harvest (Rvest) Multiple HTML Pages from a List of Urls
Adding Multiple Lag Variables Using Dplyr and for Loops
How to Run a R Language(.R) File Using Batch File
Adding Multiple Columns in a Dplyr Mutate Call
Nas Are Not Allowed in Subscripted Assignments
Why Does Dplyr's Filter Drop Na Values from a Factor Variable