Skip to contents
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, like the environment within a function. (“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:

  1. import_int() includes the lib.loc argument.
  2. 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/RtmpSeP6tc/temp_libpath486854454fe5"
#> [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 vector pkgs are installed in library paths lib.loc, and does this without attaching or even loading the packages.