Import system - additional details
Source:../vignettes/articles/c_import_additional.Rmd
c_import_additional.Rmd
library(tinycodet)
#> Run `?tinycodet::tinycodet` to open the introduction help page of 'tinycodet'.
Introduction
The previous article, “Import system - main functions”, discussed the main functions of the import system. Please read that article first before reading this article.
Miscellaneous import_ - functions
Beside the main import_
functions
(import_as()
, import_inops()
, and
import_data()
), there are 2 miscellaneous
import_
functions: import_LL()
and
import_int()
.
The import_LL()
function places specific functions from
a package in the current environment, and also locks the specified
functions to prevent modification. The primary use-case for this
function is for exposing functions inside a local environment. (“LL”
stands for “Local & Locked”.)
Example:
rm(list = ls())
import_LL("tidytable", "across")
#> exposing and locking functions to current environment ...
#> Done
ls() # notice `accross` is now exposed in this environment
#> [1] "across"
The import_int()
function directly returns an internal
function from a package. It is similar to the :::
operator,
but with 2 key differences:
-
import_int()
includes thelib.loc
argument. -
import_int()
only searches internal functions, not exported ones. This makes it clearer in your code that you’re using an internal function, instead of making it ambiguous.
The main argument is the form
argument, which is a
2-sided formula with one term on each side, the left term giving the
package name and the right term giving the name of the internal
function.
Example:
# Using through re-assignment:
fun <- import_int(tinycodet ~ .internal_paste, .libPaths())
fun("hello", "world")
#> [1] "helloworld"
# Or using directly:
import_int(
tinycodet ~ .internal_paste, .libPaths()
)("hello", "world")
#> [1] "helloworld"
S3 methods: they just work
When importing packages with tinycodet
’ import system,
S3 methods will work just fine. For example, the S3 method ”
plot()
” works with objects from the mgcv
R
package, even when imported in an alias:
import_as(~ mgcv., "mgcv") |> suppressMessages()
d <- import_data("gamair", "chicago")
# just a random model for the sake of demonstration:
model <- mgcv.$gam(death ~ s(o3median), data=d)
isS3method(f="plot", class="gam") # this is an S3 method
#> [1] TRUE
plot(model)
Also, S3 methods defined in the package will automatically be registered, and thus automatically work. For example, the following code just works:
import_as(~ dpr., "dplyr") |> suppressMessages()
import_inops("magrittr") |> suppressMessages()
d <- import_data("dplyr", "starwars")
d <- d %>% dpr.$group_by(species)
isS3method(f="arrange", class="data.frame", envir = dpr.) # this is an S3 method
#> [1] TRUE
isS3method(f="relocate", class="data.frame", envir = dpr.) # this is an S3 method
#> [1] TRUE
# this works:
d %>%
dpr.$arrange(dpr.$desc(mass)) %>%
dpr.$relocate(species, mass)
#> # A tibble: 87 × 14
#> # Groups: species [38]
#> species mass name height hair_color skin_color eye_color birth_year sex
#> <chr> <dbl> <chr> <int> <chr> <chr> <chr> <dbl> <chr>
#> 1 Hutt 1358 Jabb… 175 NA green-tan… orange 600 herm…
#> 2 Kaleesh 159 Grie… 216 none brown, wh… green, y… NA male
#> 3 Droid 140 IG-88 200 none metal red 15 none
#> 4 Human 136 Dart… 202 none white yellow 41.9 male
#> 5 Wookiee 136 Tarf… 234 brown brown blue NA male
#> 6 Human 120 Owen… 178 brown, gr… light blue 52 male
#> 7 Trandosh… 113 Bossk 190 none green red 53 male
#> 8 Wookiee 112 Chew… 228 brown unknown blue 200 male
#> 9 NA 110 Jek … 180 brown fair blue NA NA
#> 10 Besalisk 102 Dext… 198 none brown yellow NA male
#> # ℹ 77 more rows
#> # ℹ 5 more variables: gender <chr>, homeworld <chr>, films <list>,
#> # vehicles <list>, starships <list>
So when importing packages, everything works as expected, including S3 methods.
Alias attributes
One may have noticed in the “Import system - main functions” article, that aliasing a package like so:
import_as(~ tdt., "tidytable", re_exports = TRUE, dependencies = "data.table")
#> Importing packages and registering methods...
#> Done
#> You can now access the functions using `tdt.$`
#> For conflicts report, packages order, and other attributes, run `attr.import(tdt.)`
… produces several messages, including the message “For conflicts
report, packages order, and other attributes, run
attr.import()
”.
The attr.import()
function allows the user to access the
special attributes stored and locked inside the alias object. These
attributes show which imported package overwrites which imported
functions, in what order the packages are imported and so on.
Here are some examples.
Show the packages imported under the alias, and in which order the packages are imported, and from which packages the re-exported functions came from:
attr.import(tdt., "pkgs")
#> $packages_order
#> [1] "data.table" "tidytable"
#>
#> $main_package
#> [1] "tidytable"
#>
#> $re_exports.pkgs
#> [1] "data.table" "rlang" "tidyselect" "magrittr" "pillar"
Show which functions from which packages “win” conflicts:
attr.import(tdt., "conflicts")|> knitr::kable()
package | winning_conflicts |
---|---|
data.table | |
tidytable + re-exports | last, first, between, %notin%, fread, setDTthreads, fwrite, getDTthreads, data.table, %chin%, %between%, %like% |
Show the arguments used in the import_as()
call that
produced the alias object in question:
attr.import(tdt., "args")
#> $main_package
#> [1] "tidytable"
#>
#> $re_exports
#> [1] TRUE
#>
#> $dependencies
#> [1] "data.table"
#>
#> $extensions
#> NULL
#>
#> $lib.loc
#> [1] "C:/Users/Tony/AppData/Local/Temp/Rtmp6LwZgV/temp_libpath737025902176"
#> [2] "D:/Programs/R-4.4.0/library"
#>
#> $import_order
#> [1] "dependencies" "main_package" "extensions"
The help file on attr.import()
provides more details on
each of these options.
Check for package versions mismatch
The pversion_check4mismatch()
function checks if there
is any mismatch between the currently loaded packages and the packages
in the specified library path.
The pversion_report()
function gives a table of all
specified packages, with their loaded and installed versions, regardless
if there is a mismatch or not.
help.import
The help.import()
function gets the help file for a
function i
(or topic string i
), even if the
function is inside an alias object, or if the function is an unattached
function (like exposed infix operators).
Example:
import_as(~ mr., "magrittr")
import_inops(mr.)
help.import(i=mr.$add)
help.import(i=`%>%`)
help.import(i="add", alias=mr.)
Miscellaneous comments on package imports
The magrittr and
rlang packages add
“pronouns” to R: .
, . data
, .env
.
Fret not, for pronouns work regardless if you attached a package or not.
And you don’t need to use something like rlang::.data
or
rlang.$.data
for a pronoun to work. They just work.
There are some additional miscellaneous functions related to the package import system that should perhaps be mentioned also:
- the
pkg_get_deps()
function gets the dependencies (or the enhances) of a package, regardless if the package is CRAN or non-CRAN. See the help file for details. - the
pkgs %installed in% lib.loc
operator checks if the packages specified in character vectorpkgs
are installed in library pathslib.loc
, and does this without attaching or even loading the packages.