This question is inspired by the specific nature of tidytable as an intentional drop-in replacement for entire tidyverse packages and my own circumstances.
I'm developing a couple of R packages at work that rely extensively on tidytable. The R environment is quite limited and centrally controlled (and that's impossible to change) and it would be advantageous for the packages to automatically fall back on dplyr + tidyr + purrr. These are more likely to be centrally added/updated to the correct environment whether I'm around bugging the right people or not.
I'm currently using @import tidytable, as I repeatedly use a long list of its functions. Is it possible to get my package to fall back on dplyr, tidyr and purrr if tidytable fails to load? My package runs the same whether I import one or the others; but I'd prefer tidytable when available as it is noticeably faster.
I'm aware of certain workarounds for one or two functions but not across the whole package, probably because the tidytable/dplyr+tidyr+purrr match not only of functionality but also syntax is rather unusual.
Some assumptions:
R CMD checkto behave well with tests and documentation and package checks when functions require presence of a package that is inSuggests:and not inImports:. Perhaps I've done it wrong, I know it is very doable and done in many (popular) packages. So perhaps this is just a precautionary bullet ...Since the packages you need will not be in
Imports:, then when somebody doeslibrary(yourpackage), R will not automatically import the either or the other package(s). In this case, you have two options, depending on your comfort with using the.onLoador.onAttachfunctions (see?ns-hooks):Write a helper function that calls
require(tidytable)1 and, ifFALSE, then callsrequire(tidyverse)(or just the packages you really need, since loading tidyverse can be non-instantaneous). If that is alsoFALSE, thenstop(.). Call this helper function in every one of your package functions that would need it. It adds a little overhead to each function, but generally it's nearly a no-op if the package is already loaded.Or, write that function and then call it from
.onLoadonce, and it'll be executed when somebody callslibrary(yourpackage). This should also work when somebody callsyourpackage::somefuncwithout first callinglibrary(yourpackage). If you want to require that they runlibrary(yourpackage), you can instead use.onAttach, but I don't know if that adds any value here.Notes:
libraryandrequire(and their related functions), see https://stackoverflow.com/a/51263513/3358272, https://yihui.org/en/2014/07/library-vs-require/, https://r-pkgs.org/namespace.html#search-path.