I'm writing an R package and spend lots of time on the documentation vignettes. I'm wondering if i should add something like
.onAttach <- function( libname , pkgname ){
packageStartupMessage("use `browseVignettes('packagename')` to see vignettes")
}
that will show up immediately when a user calls
library(packagename)
What is the best way to inform users about package vignettes? Or is it just assumed that users will look for them without the explicit notification?
Few things to keep in mind about vignettes in the eyes of an everyday R user...
browseVignettes(package = "pkgname")
[as you have pointed out]/demos
via demo()
Thus, if you spend a considerable amount of time on the package documentation, you probably should at least indicate on startup such a feature exists.
packageStartupMessage()
within .onAttach()
for the users benefit.On package load, the console is relatively clear and the user will definitely see the red text as the contrast is relatively high between normal blue R text (assuming no crayon). However, there are a few cases where it does not make sense to alert the user to the presence of vignettes.
Thus, there is negative to a poorly implemented packageStartupMessage()
.
As a result, I would recommend introducing the startup message under four different conditions.
interactive()
. If so, then proceed:x
package loads kill the startup message until the user reinstalls the package.I'll present two solutions next that follows the tenet of (1) - (3) and then just (1) and (4) for simplicity sake.
Within this version we seek to simply check for humans, provide a break from adding a package load message, and randomly picking one hint to display. Only one dependency is needed outside of the scope of base
, the stats::runif
command to generate a probability between [0,1].
#' @importFrom stats runif
.onAttach <- function(...) {
# If interactive, hide message
# o.w. check against rng seed.
if (!interactive() || stats::runif(1) > 0.5){
return()
}
# Create a list of helpful tips
pkg_hints = c(
"Check for updates and report bugs at https://cran.r-project.org/web/packages/pkgname/.",
"Use `suppressPackageStartupMessages()` to remove package startup messages.",
"To see the user guides use `browseVignettes('pkgname')`"
)
# Randomly pick one hint
startup_hint = sample(pkg_hints, 1)
# Display hint
packageStartupMessage(paste(strwrap(startup_hint), collapse = "\n"))
}
To use a counter, we make use of the ability to save into the package's install directory and not the "working" directory / user space. This has a few problems associated with it that I'll briefly mention:
system
library (user libraries are okay).
system
library.
Of course, you could create your own folder within the user space via R_USER
or HOME
environment variables to negate these problems. (Exercise left to the reader, hint: Use Sys.getenv()
and dir.create()
.)
Regardless, one of the beauties of this function is at a later time you could probably include a "send package usage statistics" function within the package. This would actual give a reasonably accurate - phone home - statistic vs. the current RStudio CRAN mirror package download info. But, I digress.
For this method to work, we need to do a bit more prep work on the initial package supplied to CRAN. Specifically, we should probably pre-setup a counter via:
# Set working directory to package
setwd("package_dir")
# Create the inst directory if it does not exist
if(!dir.exists("inst")){
dir.create("inst")
}
# Create a counter variable
pkg_count = 0
# Save it into a .rda file
save(pkg_count, file="inst/counter.rda")
And now, onto the .onAttach()
counter implementation!
.onAttach <- function(...){
if (!interactive()) return()
# Get the install directory location of the counter
path_count = system.file("counter.rda", package = "pkgname")
# Suppress messages by default
displayMsg = FALSE
# Are we able to load the counter?
a = tryCatch(load(path_count), error = function(e){"error"}, warning = function(e){"warning"})
# Set error variable
count_error = a %in% c("error","warning")
# Check if the count is loaded
if(!count_error){
# Check if load count is low...
if(pkg_count < 10){
pkg_count = pkg_count + 1
# Try to save out
try(save(pkg_count, file = path_count), silent=TRUE)
displayMsg = T
}
}
# Display message (can be suppressed with suppressPackageStartupMessages)
if(displayMsg){
packageStartupMessage("use `browseVignettes('packagename')` to see vignettes")
}
}
Please keep in mind that if you have any package dependencies (e.g. Depend:
in DESCRIPTION
), they may have their own set of startup messages that will be displayed before the ones written in your package.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With