When developing a package, it's useful to know when a function that we want to use was introduced in R or in a dependency, so that we know whether including it will change the dependencies of our package. Is there a function that takes a function name as input and outputs the R version or the package version in which it was released?
Example:
implemented_in("list2DF()")
#> '4.0.0'
Even better if this function could work for every package and not just for base R, for example:
implemented_in("dplyr::relocate()")
#> '1.0.0'
CodePudding user response:
I made a small package for this. It doesn't extract the version in which a function was introduced but it gets all mentions of a function in the NEWS. Therefore, you can find when a function was added, but also when it was modified:
library(getnews)
getnews("paste0")
#> VERSION 2.15.0
#> ===========
#>
#> New function paste0(), an efficient version of paste(*,
#> sep=""), to be used in many places for more concise (and
#> slightly more efficient) code.
#>
#>
#> VERSION 4.0.1
#> ===========
#>
#> paste() and paste0() gain a new optional argument recycle0.
#> When set to true, zero-length arguments are recycled leading to
#> character(0) after the sep-concatenation, i.e., to the empty
#> string "" if collapse is a string and to the zero-length value
#> character(0) when collapse = NULL.
#>
#> A package whose code uses this should depend on R (>= 4.0.1).
getnews("adist")
#> VERSION 2.14.0
#> ===========
#>
#> New function adist() in package utils for computing ‘edit’
#> (generalized Levenshtein) distances between strings.
getnews("relocate", "dplyr")
#> VERSION 1.0.0
#> ===========
#> New relocate() verb makes it easy to move columns around within a
#> data frame (#4598).
#>
#>
#>
#> VERSION 1.0.3
#> ===========
#> relocate() can rename columns it relocates (#5569).
#>
#>
Created on 2022-07-09 by the reprex package (v2.0.1)
CodePudding user response:
You could search through the NAMESPACE
files of package versions to find
the first time a function has been exported. Two packages help with this:
pkgsearch
can be used to find all CRAN versions of a contributed
package, and pacs
can retrieve and read NAMESPACE
files.
A simple version (without handling any edge cases) of such a search function could look like this:
implemented_in <- function(fn, pkg) {
history <- pkgsearch::cran_package_history(pkg)
# Always search at least one version
last_without <- 0
first_with <- nrow(history) 1
# Binary search to avoid reading all NAMESPACE files
while (first_with - last_without > 1) {
next_index <- floor((last_without first_with) / 2)
version <- history[next_index, ]$Version
ns <- pacs::pac_namespace(pkg, version = version)
if (fn %in% ns$exports) {
first_with <- next_index
} else {
last_without <- next_index
}
}
history[first_with, ]$Version
}
implemented_in("relocate", "dplyr")
#> [1] "1.0.0"
However, this approach doesn't work for base R functions.