Usethis: Examples of various ways people use usethis

Created on 23 Jun 2019  Â·  26Comments  Â·  Source: r-lib/usethis

Preparation for this talk at useR! 2019 Toulouse:

DRY out your workflow with the usethis package
Jenny Bryan
In session "Programming 1", in room Saint-Exupéry
Thursday July 11, 12:06 - 12:24pm (15 mins)

Usethis is one of the packages created in the recent "conscious uncoupling" of the devtools package. Devtools is an established package that facilitates various aspects of package development. Never fear: devtools is alive and well and remains the public face of this functionality, but it has recently been split into a handful of more focused packages, under the hood. Usethis now holds functionality related to package and project setup. I'll explain the "conscious uncoupling" of devtools and describe the current features of usethis specifically. The DRY concept -- don't repeat yourself -- is well accepted as a best practice for code and it's an equally effective way to approach your development workflow. The usethis package offers functions that enact key steps of the package development process in a programmatic and documented way. This is an attractive alternative to doing everything by hand or, more realistically, copying and modifying files from one of your other packages. Usethis helps with initial setup and also with the sequential addition of features, such as specific dependencies (e.g. Rcpp, the pipe, the tidy eval toolkit) or practices (e.g. version control, testing, continuous integration).


I'd like to collect real-world examples of how people-who-are-not-me use usethis!

  • Do you use for day-to-day project setup and maintenance? Which functions are most useful?

  • Have you used it inside a package? What does that package do? Is it somewhere public and OK to mention/link?

  • Have you used it in teaching? How?

Thanks in advance and please include your website (and/or twitter handle or whatever) so that I link to the right "you" in the talk notes and so this thread is more informative.

Most helpful comment

I most regularly use create_project()/use_git()/use_github() for new projects and to toss them onto GitHub. I sometimes have to use git push -u to get my project onto GitHub the first time, but I suspect that it’s been fixed by now. I also regularly use edit_r_profile() and edit_r_environ() for fiddling around with my settings. I haven’t been doing much package development recently, but use_pipe() was well-received by teammates I mentioned it to.

I’ve used use_course() several times for workshops. Since xaringan presentations come with a lot of extra files, we typically created separate repos for exercises (example: slides repo, exercises repo, use_course code in the presentation and also emailed out before the workshop). I love use_course(), but I also kind of wish it came bundled with the tidyverse. It was an extra thing to install every time we had newcomers (and we were already fighting a bad internet connection).

I've only used use_rmarkdown_template() once (in tidiesofmarch), but I was amazed by it. I initially tried to get the set-up done manually but failed miserably at understanding the folder structured needed.

I am currently dreaming of formalizing our team’s model training process into template files that could be initiated with usethis-style functions, but I haven’t gotten to it yet.

Looking forward to your talk! There are so many goodies there that I haven’t tried out!

twitter me

All 26 comments

Today I saw it being used (well, mentioned) in taxize. In particular in this context:

> taxize::use_entrez()
Create your key from your (brand-new) account's. 
 After generating your key set it as ENTREZ_KEY in .Renviron.
 ENTREZ_KEY='youractualkeynotthisstring'
 For that, use usethis::edit_r_environ()

Which is a great way of making the process of setting up your NCBI API (for Batch Entrez) as straightforward as possible.

I use this gist I created to setup every project I start. The gist reported what my "most useful" function in usethis are.

I have also included some of the usethis exported or unexported functionalities in some packages, e.g., in this package I usethis to promote a standard folders' structure within the projects of our units.

You can mention both the gist and the package.

IMO, usethis is a crucial resource both to speed up and to maintain coherence between packages developed within the same unit.

Just to mention some space to improve I see: add the possibility to usethis not only for package (e.g., I use data, data-raw, git, GitHub not only in packages but in quite every .Rproj), and to provide a simple way to suppress, or to test for ui_*() messages (e.g. suppress_usthis_ui(), expect_usethis_ui()). Those two things are the most frustrating for me when usethis _for_ (the first) or _in_ (the second) an R project.

I most regularly use create_project()/use_git()/use_github() for new projects and to toss them onto GitHub. I sometimes have to use git push -u to get my project onto GitHub the first time, but I suspect that it’s been fixed by now. I also regularly use edit_r_profile() and edit_r_environ() for fiddling around with my settings. I haven’t been doing much package development recently, but use_pipe() was well-received by teammates I mentioned it to.

I’ve used use_course() several times for workshops. Since xaringan presentations come with a lot of extra files, we typically created separate repos for exercises (example: slides repo, exercises repo, use_course code in the presentation and also emailed out before the workshop). I love use_course(), but I also kind of wish it came bundled with the tidyverse. It was an extra thing to install every time we had newcomers (and we were already fighting a bad internet connection).

I've only used use_rmarkdown_template() once (in tidiesofmarch), but I was amazed by it. I initially tried to get the set-up done manually but failed miserably at understanding the folder structured needed.

I am currently dreaming of formalizing our team’s model training process into template files that could be initiated with usethis-style functions, but I haven’t gotten to it yet.

Looking forward to your talk! There are so many goodies there that I haven’t tried out!

twitter me

I use it a few different ways. From a teaching perspective:

  • use_course() is fantastic for running workshops or for helping to get complete novices set up with a structured project. It's genuinely changed the way I think about designing workshop content because it's so easy to get participants started with the exact materials you want them to have. I think it saves 30 mins of pain at the start of every class. So far I've used it for an "introduction to R" class, a data visualisation workshop and a "computational cognitive science" class.

From the developer side:

  • For package development I'm constantly using use_package(), use_coverage(), use_travis(), use_testthat() etc. In theory none of these are complicated operations but being able to do it in a single command rather than having to break my train of thought to remember "okay wait, remind me how the travis.yml file is formatted" is just wonderful. They remove a lot of the little frictions that used to drive me to distraction when coding.
  • I've just started using the pr_init() family for pull requests, and I think that will eventually have the same feeling. I'm very new to making pull requests and I find it helpful to have a family of functions that help standardise the process and prevent me from doing something silly like making a PR from master.
  • I just discovered git_sitrep() and git_vaccinate() and I love them!

But honestly it's just a fantastic package and I keep finding new an interesting things in there to smooth my workflow and make my life just a little bit easier.

(Twitter handle: @djnavarro, Website: https://compcogscisydney.org)

I contributed the taxize function mentioned in the 1st comment by @aldomann because usethis influenced how I think about helping users setup stuff so I was glad to read that. 😉

When making editorial comments at rOpenSci software review / when working on the corresponding dev guide we try to add mentions of usethis functions for various things (README creation, package level doc skeleton, etc.). http://devguide.ropensci.org

Locke Data's https://github.com/lockedata/starters can be viewed as a collection of usethis recipes.

Twitter me

When building a package I keep a script in my "exclude" folder where I put all my usethis stuff, along with some git commands, it's not meant to be executed in one go, I just execute the lines when I need them. It's a variation of the following :

usethis::use_directory("exclude", ignore = TRUE)
usethis::use_build_ignore("exclude")
usethis::use_git_ignore("exclude")
usethis::use_gpl3_license("GPL-3")

usethis::use_package("utils")
usethis::use_package("rlang")
usethis::use_package("dplyr")

usethis::use_pipe()

usethis::use_testthat()
usethis::use_readme_rmd()

usethis::use_version()
usethis::use_news_md()

shell("git remote add origin https://github.com/moodymudskipper/mypkg.git", intern = TRUE)
shell("git push -u origin master", intern = TRUE)

devtools::install_github("moodymudskipper/mypkg")

I'd like to have a cleaner template, including use_description and more when I get the chance to study the package in depth, so far I just copy and paste it from a previous package and edit.

Love it so much for package dev I've started wrapping up pieces of drake pipeline dev for myself: https://github.com/MilesMcBain/dflow

Not only does this copy the usethis formula, it uses usethis to do so.

I know you (@jennybc) know all about this already (and we are super-grateful for all your extra help), we built a day-long workshop around usethis for the Uncoast-Unconf: https://uncoast-unconf.github.io/uu-2019-day-zero (with Haley Jeppson (tw:@heyhayhay__) and Amelia McNamara (tw:@AmeliaMN))

In a package, I use usethis::use_template() (and other usethis functions) in templating code in vegawidget, which lets someone build import and re-export its rendering functions; this gets used in altair.

Day-to-day, usethis is so ingrained in my processes that it is difficult to focus on particular functions, but I will note that the pr_*() functions border on magic 😃

usethis and devtools have both been instrumental in pushing me and getting me to create R packages. They both have inspired me to create packages designed to make it easier for biomedical researchers doing reproducible and open science (packages rostools and its framework are still in dev, but I've got one package about it on CRAN (prodigenr) which is similar in spirit to rrtools).

While I use most use_* functions quite regularly for package development, I also use use_package() a lot for data analysis projects, as well as use_git(), use_code_of_conduct() and the licenses functions, use_r() to quickly create an R file, and use_tidy_versions() to list dependency versions. browse_github_pat() is so amazing for setting up a PAT... I always forget how to do that, so this helps a lot!

Update: I just wanted to make sure this was super clear and explicit... I would not ever have even attempted to create R packages if it wasn't for devtools and usethis making this easier and more accessible for me. I am no programmer, I have no strong education in CS or math/computing-heavy statistics. As wonderful as "Writing R Extensions" is as a resource, it is not accessible to people like me... and there are a lot of people like me in biomedical sciences... (or just in general!)... so thank you for making these packages!

I'm responding to your tweet here: https://twitter.com/JennyBryan/status/1142813620440453125
I'm not like you and I don't use usethis. Can you include a reference to people like me please who get on perfectly fine with base R to create a package. To put an example to it: what is the point of use_mit_license when, well, you can just use the MIT license. And what is the point of use_package when you can use require or library in base R? Isn't this all just creating layers and layers of thin wrappers, when you could instead spend the time to teach how to do it in base R?

To be clear : lots of people clearly find the package valuable which clearly corroborates it. I am writing down my current questions, in response to your tweet asking for them, so that you can consider addressing them in your presentation. In other words: what's wrong with base R?

I regularly use usethis::create_package() when I want to create a new R package project (either because I want to test something in a skeleton package, or because I'm looking to build something real).

usethis::use_travis() and usethis::use_appveyor() and friends (basically, anything that hooks you up with CI) are a godsend, especially since best practices around how the various YAML metadata files should be constructed change over time. I also use usethis::use_vignette() and usethis::use_test() a lot, just because the files are generated with helpful templates and are created where they need to be.

Basically, with usethis, as long as I know _what_ I want to do, I no longer need to remember the exact mechanics of _how_ to do it -- usethis kindly remembers for me. So I have brain power to spare on other parts of the project :-)

@mattdowle

And what is the point of use_package when you can use require or library in base R?

These functions have completely different functionality https://usethis.r-lib.org/reference/use_package.html

Can you include a reference to people like me please who get on perfectly fine with base R to create a package.

One analogy to this is that there are people who are fine using Rgui.exe, and others who prefer more featureful IDEs. Likewise, usethis is on the side of automating workflows and reducing repetitions. It provides IDE-oriented features in R, that can be reused by editors like RStudio or ESS. I'm sure there are other ways to automate workflow than usethis, but this package probably fits best our own practice of developing R packages.

I find usethis really useful to set up package projects and specifically to remember how things get done.
All the functions related to https://r-pkgs.org/whole-game.html are more than useful.

Also I regurlarly use use_version too in a release process for internal package. The interactivity of the function makes things smooth. I often complete with usethis::edit_file("NEWS.md") for cleaning and edition before release.

Basically, I see usethis has a tool to get more efficient : It helps understand what is important and how to do it, without becoming a great master of R package development. You can follow guidelines to quickly produce a package, then spend some time to understand what is under hood until you reach "writing R extension" docs if interested.

Functions for CI are really useful in regard of efficiency because writing a working yaml can be a real pain until you've understand what is a CI, how it worked and made your own template to reuse. Sharing one for all in usethis is the same and much more clever IMO.

At last, I use regularly ui_* functions in some tools where I want interactivity to be often use and central in the experience. I am not sure that usethis is there final home but damn they are useful to create some cli interactivity very efficiently.

One thing I can confirm : usethis is set of helpers functions that brings a clever framework to allow everyone to produce a tool for sharing. There is no more reason to not produce a package and send a folder of script instead. R user I support at work benefit a lot from this.

I am a recent usethis convert. :) Most usethis helpers are now superior to my old package workflow.

use_readme_rmd(), use_vignette() use_code_of_conduct() are the ones I used most recently, and I really should use use_pkgdown_travis() because it is far better than my current pkgdown configs. But there are a lot more gems. Usually whenever I change something on a package's infrastructure, I take a look at usethis first, to see if it has a helper function for it.

I think a very important aspect of usethis is that it serves as a collection of best practices for package development, with super code and documentation. E.g. if you want to check what the best way is to use the MIT license in your package, look at use_mit_license() and you'll get info that is non-trivial, because of CRAN's non-standard licensing requirements conflicting common open source practices. I.e. LICENSE must be a two line note on CRAN, and the common open source practice is that LICENSE is the full license text, which usethis helpfully puts in LICENSE.md as a workaround, and makes sure R ignores it, to avoid problems on CRAN.

use_mit_license() just helped me straighten out processx:
https://github.com/r-lib/processx/commit/17a4b25b68b50ca4cb0b2ce780220d0fd53f5df7

I use usethis to avoid having to remember the fiddly little bits of how exactly to make sure my package dependencies are formatted correctly. In particular, leaning about use_pipe was SUPER helpful!

@ThinkR-open, we use {usethis} functions stored in a R script file to help us remind all the different steps necessary to build and deploy packages. Storing this function in all our packages allows to keep trace of history of actions that were realised during development. This is for traceability of actions. This is also because we love to automate things: when reducing manual operations, you reduce potential sources of errors.

To do so, we add a file, called "dev_history.R", generally at the root of our package. This is the first file of all packages, right after we used the RStudio graphical interface (or usethis) to create a new package. We also have an internal package to help generate it.
You can find some version of this "dev_history.R" file here in {attachment} or here in {golem}

Also, if you use {golem}, the package creation directly creates a "dev" folder with these "dev_history.R" files, which are here to help users in the development of their golem: https://github.com/ThinkR-open/golem/tree/master/inst/shinyexample/dev . {usethis} is highly used in these files...

Finally, while dealing with server installations, it is sometimes difficult to find where to store the ".Rprofile" file, depending on the configuration of user sessions. usethis::edit_r_profile() does a great job to put the file at the right place.

This package is really useful ! Thank you for it.

devtools and then usethis have been a core part of my workflow for years. I think I've written over 30 packages in that time, not including ones I make during training. usethis has saved me many hours and many mistakes.

We use usethis as the basis for starters (lockedata/starters on here) to help put together what we believe to be the best practice packages so that we can be more productive and consistent.

Anyone who doesn't use usethis as a package author with multiple packages under their belt and a plan to write more is missing a trick imo 😉

I use usethis so I don't have to remember everything I need to do, sort of as a package skeleton.

I'm only commenting because I use usethis in RxODE as well as one step in adding a pre-compiled RxODE model to another package.

@ijlyttle has already covered the uncoast unconf, but I just wanted to chime in and say that after the awesome experience of using usethis at the unconf, I amped up my use of the package in my Advanced Statistical Software class this past semester. We learned package development following Ian's slides, and students came back to them again and again as they were working on their final projects (many of which were R packages). Of course the initial directory structure is great, but devtools has had some version of that for a while. What I was most grateful for were things like use_package(), use_test(), etc.

The stuff for git setup is also invaluable, like git_sitrep(), use_git_config(), git_vaccinate(), etc.

In case it's useful, here is my course site: http://www.amelia.mn/STAT360/ And of course I'm on twitter as @AmeliaMN.

A little late to the game, but I wanted to share the coolest way I've used use_course, which is to deliver a coding exam.

Students in my R class take exams on monitor-able classroom computers. This comes with setup stress:

They need the exam dataset, but...

  • Referencing data via url is bad, because sometimes want to block internet when the exam starts.
  • Having them download a dataset manually is bad, because they are on unfamiliar computers and get frustrated with path/folder management.

They need an exam template .Rmd file (for easier grading), but...

  • I want to give this template to reference some setup source scripts
  • I want these templates not to be saved under silly names

Perhaps most importantly, I want these materials to be accessible for 5 minutes of setup, and then hidden once again, so future classes (whether 1 hour later or 1 year later) can't find them.

All this was easily solved by bundling the materials, having them run a one-line use_course from my github repo, and then re-private-ifying the repo.

It was literally just POOF the exam file is open, you may begin. So awesome.


Also, I'm but a humble mid-level R user, but here are my thoughts on @mattdowle 's questions:

To put an example to it: what is the point of use_mit_license when, well, you can just use the MIT license.

For people like me who don't make packages often, where to put these things and how to format them is super new and would have required a ton of Googling and double checking and looking at other people's source files. use_mit_license saves me a few minutes and some cognitive load stress.

And what is the point of use_package when you can use require or library in base R?

use_package also documents the dependencies properly; again, maybe frivolous to a seasoned package writer but a stressful source of possible major error for me!

Isn't this all just creating layers and layers of thin wrappers, when you could instead spend the time to teach how to do it in base R?

What's wrong with layers of thin wrappers, if they make the work of developers easier, less painful, more efficient? In some sense, isn't all coding a series of wrappers - should we all be programming directly in binary? :P

Sincerely asking: Is there any added value to taking the time to craft all these file structures manually, especially for those of us who don't make packages often and will probably forget by the next time we start one?

What's wrong with base R?

I don't think there needs to be anything "wrong" or "bad" about a tool before it's worthwhile to create potentially useful alternate tools, so long as the alternates don't encourage bad practice.

I used usethis in the exampletestr package (which is on CRAN). exampletestr helps people to create testthat tests based on the @examples in their package documentation; it's the closest thing R has to Python's docstrings. This involves a lot of fiddling around with file creation and package paths: use_testthat(), proj_path() and more were useful for this. The messaging functions like ui_todo() were also useful.
Interestingly, in the end, I think I preferred proj_path() to using rprojroot.

I use usethis in a file stored in the parent directory of all my project/packages. I always open it in the RStudio package creation session. Every command I run about package development is saved in this file.

It might be a little confuse but I always found what I want if I already used it. And I rerun and rerun again the Repeated section.

library(devtools)
library(usethis)
library(testthat)
library(pkgdown)

#### One time ####

# create_package("Documents/RCodes/yatah")
# create_tidy_package()
# use_git()
# use_cc0_license("Antoine Bichat")
# use_gpl3_license("Antoine Bichat")
# git_sitrep()
# use_github()
# use_testthat()
# use_roxygen_md()

# use_r("treedist")
# use_test(name = "spec-chr")
# use_data(abundances)

# use_readme_rmd()
# use_news_md()
# use_travis()
# use_appveyor()
# use_coverage(type = c("codecov"))
# use_version()
# use_vignette("Taxonomy_of_Gammaproteobacteria")
# use_logo(img = "../../Divers/stickers/yatah_hexa.png")
# use_pipe()

#### Badges ####

library(badgecreatr)
# badge_last_change()
# badge_packageversion()
# badge_cran("yatah")
# badge_license()
# badge_lifecycle(lifecycle = "maturing")

#### Repeated ####

load_all()

document()
attachment::att_to_description()
use_tidy_description()

# covr::package_coverage()

spell_check()
# spelling::update_wordlist()

test()

goodpractice::gp()
devtools::check()

build()


#### Site ####
# Install and restart first

pkgdown::build_site()
pkgdown::clean_site()
rmarkdown::render("README.Rmd"); file.remove("README.html")

Thanks @kbodwin for replying to my questions. I now see that usethis is a little different to what I thought it was. Many of the use-cases in this thread remind me of utils::package.skeleton which is indeed very useful.

To put an example to it: what is the point of use_mit_license when, well, you can just use the MIT license.

For people like me who don't make packages often, where to put these things and how to format them is super new and would have required a ton of Googling and double checking and looking at other people's source files. use_mit_license saves me a few minutes and some cognitive load stress.

Ok fair point, thanks. utils::package.skeleton has no mention of license so I do see the difficulty.

And what is the point of use_package when you can use require or library in base R?

use_package also documents the dependencies properly; again, maybe frivolous to a seasoned package writer but a stressful source of possible major error for me!

What is meant by document the dependencies properly please? I thought use_package() is a wrapper around require() or library().

Isn't this all just creating layers and layers of thin wrappers, when you could instead spend the time to teach how to do it in base R?

What's wrong with layers of thin wrappers, if they make the work of developers easier, less painful, more efficient? In some sense, isn't all coding a series of wrappers - should we all be programming directly in binary? :P

In general I agree. But in practice I've seen a not-insignificant amount of problems reported by people writing packages that use data.table caused by the Roxygen/RStudio wrappers not working properly. Either the NAMESPACE and/or DESCRIPTION file was not written or updated properly and it made it harder to debug because there was a layer added on top. We had to debug the extra layer which we didn't know anything about. To be strictly correct, communication over what goes wrong in that layer was so hard and incomplete that I still don't know why people struggle with that or what the problem is. An extra layer is something else to go wrong and debug. However, if it all works properly all the time, now and in the future, on all platforms, then I agree there's nothing wrong with wrappers.

Sincerely asking: Is there any added value to taking the time to craft all these file structures manually, especially for those of us who don't make packages often and will probably forget by the next time we start one?

This aspect of usethis (avoiding crafting file structure manually) wasn't in my mind really. That wasn't what I was asking about. I was really only asking specifically about use_package being a wrapper around require or library.

What's wrong with base R?

I don't think there needs to be anything "wrong" or "bad" about a tool before it's worthwhile to create potentially useful alternate tools, so long as the alternates don't encourage bad practice.

I realize I should have been more specific in that question rather than leaving it to context. I really meant "what's wrong with require or library in base R that the use_package wrapper is better for"?

@mattdowle have you looked at the documentation for use_package()? It "adds a CRAN package dependency to DESCRIPTION and offers a little advice about how to best use it." It's to avoid those issues with NAMESPACE and DESCRIPTION you're talking about, when people manually add dependencies.

I realize I should have been more specific in that question rather than leaving it to context. I really meant "what's wrong with require or library in base R that the use_package wrapper is better for"?

@mattdowle, from an usethis user POV, when I develop a package I never ever use library() nor require(). Both interact with the user environment directly. Moreover, using those functions in a package-function's body make the mentioned interaction happen when the user calls the function the first time (and not when the package is loaded). Maybe, a better approach would be use requireNamespace("desiredpackage"), and next call desiredpackage::desired_function().

On the contrary, I declare the package dependencies in the corresponding section of the DESCRIPTION file (using mainly Imports or Suggests). Next, I always call desiredpackage::desired_function() to use my desired function from that desired package into a function of my package (you can read more about this here, just below the table reported).

Calling use_package("desiredpackage") on the command line permits me to avoid to open and manually modify DESCRIPTION every time I need another package. It let me free to remain focused on my development purpose, maintaining my eyes consistently on the same script all the time too. Moreover (and most important!!) I cannot forget any commas doing that ;-)

So, use_package() may have a minimal impact on my workflow, but it is enough for me to _usethis_! :-) It does only a tiny thing, but it did it, and (IMO) it did it well!

Closing now since the talk is done — thanks to everyone for their help!

Was this page helpful?
0 / 5 - 0 ratings