R Packages - What is the file 'zzz.R' used for? - r

I'm planning to condense some of my code into a package, and was looking at the source of a few published packages on CRAN as a guide. I notice many packages include the file R\zzz.R, so I presume there must be some convention surrounding this.
However, I cannot find any mention of zzz.R in the official Writing R Extensions guide. What is this file for, and do I need to include one in my package? Why is it named the way it is - why not zzzz.R?

It's a file where one usually puts actions on load of the package. It is tradition/convention that it's called zzz.R and could be called anything.R
You only need to include this if you want you package to do something out of the ordinary when it loads. Keep looking at what people put in there and you'll begin to get a sense of what they're used for.

This zzz.R file was also mentioned by Hadley Wickham in his book "R packages", at the bottom of "When you do need side-effects" section.
https://r-pkgs.org/Code.html#when-you-do-need-side-effects
If you use .onLoad(), consider using .onUnload() to clean up any side effects. By convention, .onLoad() and friends are usually saved in a file called R/zzz.R. (Note that .First.lib() and .Last.lib() are old versions of .onLoad() and .onUnload() and should no longer be used.)

Related

Where to put R files that generate package data

I am currently developing an R package and want it to be as clean as possible, so I try to resolve all WARNINGs and NOTEs displayed by devtools::check().
One of these notes is related to some code I use for generating sample data to go with the package:
checking top-level files ... NOTE
Non-standard file/directory found at top level:
'generate_sample_data.R'
It's an R script currently placed in the package root directory and not meant to be distributed with the package (because it doesn't really seem useful to include)
So here's my question:
Where should I put such a file or how do I tell R to leave it be?
Is .Rbuildignore the right way to go?
Currently devtools::build() puts the R script in the final package, so I shouldn't just ignore the NOTE.
As suggested in http://r-pkgs.had.co.nz/data.html, it makes sense to use ./data-raw/ for scripts/functions that are necessary for creating/updating data but not something you need in the package itself. After adding ./data-raw/ to ./.Rbuildignore, the package generation should ignore anything within that directory. (And, as you commented, there is a helper-function devtools::use_data_raw().)

non standard file "data-raw" note on building/checking a package in R

I get this warning
Non-standard file/directory found at top level:
‘data-raw’
when building my package, even there is the recommendation of creating this folder to create package data http://r-pkgs.had.co.nz/data.html#data-sysdata
Any comments on that or do I need a specific setting to get rid of this message.
When used, data-raw should be added to .Rbuildignore. As explained in the Data section of Hadley's R-Packages book (also linked in the question)
Often, the data you include in data/ is a cleaned up version of raw data you’ve gathered from elsewhere. I highly recommend taking the time to include the code used to do this in the source version of your package. This will make it easy for you to update or reproduce your version of the data. I suggest that you put this code in data-raw/. You don’t need it in the bundled version of your package, so also add it to .Rbuildignore. Do all this in one step with:
usethis::use_data_raw()

why roxygen2 does not automatically update "Imports" in DESCRIPTION file?

I am trying to follow closely #hadley's book to learn best practices in writing R packages. And I was thrilled to read these lines about the philosophy of the book:
anything that can be automated, should be automated. Do as little as
possible by hand. Do as much as possible with functions.
So when I was reading about dependencies and the (sort of) confusing differences between import directives in the NAMESPACE file and the "Imports:" field in the DESCRIPTION file, I was hoping that roxygen2 would automatically handle both of them. After all
Every package mentioned in NAMESPACE must also be present in the
Imports or Depends fields.
I was hoping that roxygen2 would take every #import in my functions and make sure it is included in the DESCRIPTION file. But it does not do that automatically.
So I either have to add it manually to the DESCRIPTION file or almost manually using devtools::use_package.
Looking around for an answer, I found this question in SO, where #hadley confirms in the comments that
Currently, the namespace roclet will modify NAMESPACE but not
DESCRIPTION
and other posts (e.g. here or here) where collate_roclet is discussed, but "This only matters if your code has side-effects; most commonly because you’re using S4".
I wonder:
the reason that DESCRIPTION is not automatically updated (sort of contradicting the aforementioned philosophy, which is presumably shared by roxygen2) and
If someone has already crafted a way to do it
I have written a little R package for that task:
https://github.com/markusdumke/pkghelper
It scans the R Code and NAMESPACE for packages in use and adds them to the Imports section.
The namespace_roclet edits the NAMESPACE file based on the tags added in the script before the function. As there are three types of dependencies (Depends, Imports, and Suggests), a similar method as used by the namespace_roclet would require three different tags (notice Imports should be a different one, to differentiate it from the packages to attach in NAMESPACE).
If you are willing to take a semi-automated process, you could identify the packages you have used and add the missing ones to DESCRIPTION, in the adequate sections.
library(reinstallr)
package.dir <- getwd()
base_path <- normalizePath(package.dir)
files <- list.files(file.path(base_path, "R"), full.names = TRUE)
packages <- unique(reinstallr:::scan_for_packages(files)$package)
packages
Regarding the two bullets you wonder about at the bottom:
Updates to the DESCRIPTION file could be further automated with additional roclets, however already >4 years ago such a pull request was deferred:
https://github.com/klutometis/roxygen/pull/76
I have to assume that the guys would indeed rather have you use the devtools package for updating the DESCRIPTION file, instead of adding this to roxygen2. So in that sense, devtools would be the first available choice

I'm writing a package. How can make it such that when library(my_package) is called, other packages are loaded as well?

Title should be pretty clear I hope. I'm writing a package called forecasting, with imports for dplyr among other packages. With the imports written in to the DESCRIPTION file, I am able to force these other packages to be installed along with forecasting - is there an equivalent way to do this for the loading of the package? In other words, is there a way that when I load my package with library(forecasting), it automatically also loads dplyr and the other packages?
Thanks
Yes.
Re-read "Writing R Extensions". The Depends: forces both the initial installation as well as the loading of the depended-upon packages.
But these days you want Imports: along with importFrom() in the NAMESPACE file which is more fine-grained.
But first things first: get it working with Depends.
Edit:
Opps you're correct, the documentation I referenced is not a primary source. Perhaps this is better:
From the R documentation:
The ‘Depends’ field gives a comma-separated list of package names which this package depends on. Those packages will be attached before the current package when library or require is called.
and
The ‘Imports’ field lists packages whose namespaces are imported from (as specified in the NAMESPACE file) but which do not need to be attached. Namespaces accessed by the ‘::’ and ‘:::’ operators must be listed here, or in ‘Suggests’ or ‘Enhances’
Original:
From the R packages documentation:
Adding a package dependency here [the DESCRIPTION file] ensures that it’ll be installed. However, it does not mean that it will be attached along with your package (i.e., library(x)). The best practice is to explicitly refer to external functions using the syntax package::function(). This makes it very easy to identify which functions live outside of your package. This is especially useful when you read your code in the future.

R -- Vignettes that are not made by Sweave possible?

Can I include some PDF in the pkg/doc folder so that the vignette function works, but no corresponding Rnw, Rtex, etc exists?
I am thinking of slides or documents containing markdown text weaved with R chunks, which have a different build process and hence different file extensions.
The writing R extensions guide suggests that it should be possible to include documents which can not be build at installation time, but the vignette function seems to look for files with special extensions (Rnw, Rtex, etc) and also for a file called vignette.rds.
Any hints are appreciated.
I asked about this several years ago, and while Fritz Leisch is amenable to the idea, he hasn't had the time to implement it.
(Cross-posted from a response I just left on R-help:)
As a workaround, you could include your own xvignette function in your package: see below.
It won't show you indices, but it will pick up any appropriately named file that you include in the inst/doc directory of your
package ...
xvignette <- function(vname,pkg,ext="pdf") {
vname <- paste(vname,ext,sep=".")
fn <- system.file("doc",vname,package=pkg)
if (nchar(fn)==0) stop("file not found")
utils:::print.vignette(list(pdf=fn))
invisible(fn)
}
You'll have to somehow alert your package users to the fact that this alternative documentation exists -- perhaps in the help file for the package itself.
You might fill in the default value of pkg above with your package name to make it easier on the user: I thought about using some variant of getPackageName(environment(xvignette)) to do it automatically, but that seems too complicated ...
Brian Ripley also mentioned in his response to the question that:
At present vignette() means Sweave documents, as only they have
metadata like titles. This is planned to be changed soon.
... but I don't know what "soon" means (it will be about 6 months until 2.14.0 comes out, I think)
edit: http://article.gmane.org/gmane.comp.lang.r.devel/28449 details another workaround (creating a dummy vignette that incorporates the existing PDF file)
edit 2: And
here's what Yihui Xie has to say about including knitr-based vignettes in packages (essentially another "dummy vignette" strategy)
vignette about non-Sweave vignettes from the R.rsp package
This is supported natively as of R 3.0.0, see http://yihui.name/knitr/demo/vignette/.
Instructions to use knitr as vignette engine boil down to:
add %\VignetteEngine{knitr::knitr} to the Rnw source document (note you still need %\VignetteIndexEntry{} as before)
specify VignetteBuilder: knitr in the package DESCRIPTION file
add Suggests: knitr in DESCRIPTION if knitr is needed only for vignettes
See also the official R documentation on that topic.

Resources