<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/automatic-tools-for-improving-r-packages/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://maelle.github.io/2017/06/17/automatictools/"> Maëlle</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>On Tuesday I gave a talk at a meetup of the R users group of Barcelona. I got to choose the topic of my talk, and decided I’d like to expand a bit on <a rel="nofollow" href="https://twitter.com/ma_salmon/status/824646744688488450" target="_blank">a recent tweet of mine</a>. There are tools that help you improve your R packages, some of them are not famous enough yet in my opinion, so I was happy to help spread the word! I <a rel="nofollow" href="http://rpubs.com/masalmon/282469" target="_blank">published my slides online</a> but thought that a blog post would be nice as well.</p>
<p><img alt="" src="https://i2.wp.com/maelle.github.io/figure/source/2017-06-17-automatictools/tweets.png?w=456" data-recalc-dims="1"></p>
<p><span></span></p>
<p>During my talk at RUG BCN, for each tool I gave a short introduction and then applied it to a small package I had created for the occasion. In that post I’ll just shortly present each tool. Most of them are only <em>automatic</em> because they <em>automatically</em> provide you with a list of things to fix, but they won’t do the work for you, sorry. If you have an R package you develop at hand, I’d really advise you to apply them on it and see what you get! I concentrated on tools improving the coding style, the package structure, testing, the documentation, but not features and performance.</p>
<p>Note: before my talk <a rel="nofollow" href="https://twitter.com/lucacerone?lang=es" target="_blank">Luca Cerone</a> gave a short introduction to package development with <code>devtools</code> and <code>roxygen2</code>. This is how I develop packages now although the first package I contributed to, <a rel="nofollow" href="https://cran.r-project.org/web/packages/surveillance/index.html" target="_blank"><code>surveillance</code></a>, has separate man pages, a NAMESPACE maintained by hand, etc. I gave its maintainer a hard time with all my stupid beginner mistakes! Thankfully Sebastian was always patient and nice. In any case, if you want to start developping packages you should definitely read <a rel="nofollow" href="http://r-pkgs.had.co.nz/" target="_blank">Hadley Wickham’s book</a>, it’s a good one! I read it all once I started upping my package game – this upping being a continuous process of course.</p>
<h1>The basics: run R CMD check!</h1>
<p>In his talk Luca said that when he develops a package he often doesn’t have time to check it passes R CMD check, which made me die inside a little bit. I totally understand the lack of time but I think that R CMD check complains about important stuff, and most often unknown NOTE, WARNING or ERROR messages can be googled and solved, and one learns something. So please do run R CMD check!</p>
<p><img alt="" src="https://i2.wp.com/maelle.github.io/figure/source/2017-06-17-automatictools/runrcmdcheck.jpeg?w=456" data-recalc-dims="1"></p>
<p>The R-Lady that uploaded this picture to the Meetup event told me that this is my “Run R CMD check, you fools!” face (she actually said <em>Usad el R CMD check, malditos!!!</em>).</p>
<h1><code>lintr</code>, Static Code Analysis for R</h1>
<p>I then presented Jim Hester’s <code>lintr</code> package which allows you to check some stuff in your code without running it. It will for instance tell you if you used camel case instead of snake case for a variable name, or if you defined a variable without using it afterwards. The README of the <a rel="nofollow" href="https://github.com/jimhester/lintr" target="_blank">Github repository of the package</a> provides a list of available linters, each linter being one of these annoying, hum useful, checks.</p>
<p>How does one use <code>lintr</code>? Just by typing <code>lintr::lint_package()</code> at the root of the package folder. This week I applied it to a package of mine and spent some time adding white space that made my code prettier. In my opinion using <code>lintr</code> helps you maintain a code that is nice to read, which is cool because then you, future you or another human can concentrate on important stuff when reading it.</p>
<p>I mentioned two small tips as well.</p>
<h2>How to customize the <code>lintr</code> linters?</h2>
<p>For that one needs to create a .lintr file at the root of the package (and add it to .Rbuildignore). Here is an example of the content of such a file:</p>
<div>
<pre><code><span>with_defaults</span><span>(</span><span>camel_case_linter</span><span> </span><span>=</span><span> </span><span>NULL</span><span>,</span><span> </span><span># you prefer camel case </span><span> </span><span>snake_case_linter</span><span>,</span><span> </span><span># so flag snake case
</span><span> </span><span>line_length_linter</span><span>(</span><span>120</span><span>))</span><span> </span><span># you love long lines
</span></code></pre>
</div>
<h2>How to never ever ignore <code>lintr</code> output</h2>
<p>You can add an unit test for <code>lintr</code>! Why would one ever want to do that? Well, you might want to force yourself, or contributors to your package, to respect some rules. The test would be:</p>
<div>
<pre><code><span>if</span><span> </span><span>(</span><span>requireNamespace</span><span>(</span><span>&quot;lintr&quot;</span><span>,</span><span> </span><span>quietly</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>))</span><span> </span><span>{</span><span>
</span><span>context</span><span>(</span><span>&quot;lints&quot;</span><span>)</span><span>
</span><span>test_that</span><span>(</span><span>&quot;Package Style&quot;</span><span>,</span><span> </span><span>{</span><span>
</span><span>lintr</span><span>::</span><span>expect_lint_free</span><span>()</span><span>
</span><span>})</span><span>
</span><span>}</span><span>
</span></code></pre>
</div>
<p>After I published my slides <a rel="nofollow" href="https://twitter.com/najkoja/status/874889344888320000" target="_blank">someone added such a test to one of his packages</a> which made me very proud.</p>
<p>One tip I forgot to mention during my talk is how to add exceptions, I was far too strict!</p>
<h2>How to exclude lines from <code>lintr</code> checks</h2>
<p>For that either put <code># nolint</code> at the end of the line or <code># nolint start</code> and <code># nolint end</code> before and after a block of lines you’d like to exclude. A good example is for instance a very long line that you can’t break because it contains a very long URL.</p>
<h1><code>goodpractice</code>, Advice on R Package Building</h1>
<p>This package by Gabor Csardi can only be installed <a rel="nofollow" href="https://github.com/mangothecat/goodpractice" target="_blank">from Github</a>. It integrates a variety of tools, including <code>lintr</code>, for providing “Advice (that) includes functions and syntax to avoid, package structure, code complexity, code formatting, etc.”. For instance, <code>goodpractice</code> uses <a rel="nofollow" href="https://github.com/mangothecat/cyclocomp" target="_blank"><code>cyclocomp</code></a> to check whether any of your functions is too complex. A participant of the meetup told me she got a lot of messages when running <code>goodpractice::gp()</code> on her first package, which is great because it means <code>goodpractice</code> will really have provided her with useful guidance. Some things that <code>goodpractice::gp()</code> will flag might be necessary features of your package, but in general it’s a nice list to read. Note: you can only run <code>goodpractice::gp()</code> once R CMD check passes.</p>
<p><a rel="nofollow" href="https://twitter.com/romain_francois?lang=es" target="_blank">Romain François</a> who came to the Meetup from Montpellier (thanks, Romain!) asked me if I had ever run <code>goodpractice::gp()</code> on famous packages like <code>dplyr</code>. I haven’t but since the default advice of <code>goodpractice</code> seems quite consistent with the advice in Hadley Wickham’s book, I doubt I’d find anything interesting.</p>
<p>At <a rel="nofollow" href="https://github.com/ropensci/onboarding" target="_blank">rOpenSci onboarding</a>, we run <code>goodpractice::gp()</code> on every submitted package as part of the editorial checks, which makes me like this tool a bit more every week. It’s actually tunable but the defaults are so great that I never needed to tune it!</p>
<p>I was asked when to run <code>goodpractice::gp()</code> and I’d say once in a while, e.g. before submitting a package to CRAN for the first time, or after creating its first working version.</p>
<h1><code>devtools::spell_check()</code></h1>
<p>This function was written by Jeroen Ooms and is supported by his <a rel="nofollow" href="https://github.com/ropensci/hunspell" target="_blank"><code>hunspell</code> package</a>. It will look for possible typos in the documentation of a package. In the output, there might be quite a few false positives, e.g. the name of an API, but I strongly believe that its helping you find typos in the documentation compensates the effort of reading the whole list of potential typos.</p>
<p>I’ve noticed that <code>devtools::release()</code>, which one can use when submitting a package to CRAN, now includes the output of <code>devtools::spell_check()</code>. It helped me find a typo at the last minute in one of my packages! Typos might not be that bad, but a typo-free documentation looks much better.</p>
<p><img alt="" src="https://i1.wp.com/maelle.github.io/figure/source/2017-06-17-automatictools/audience.jpeg?w=456" data-recalc-dims="1"></p>
<h2><code>pkgdown</code>, generate static html documentation for an R package</h2>
<p>This last tool was the only one that’s truly automatic. This package was created by Hadley Wickham and is currently only <a rel="nofollow" href="https://github.com/hadley/pkgdown" target="_blank">on Github</a>. It allows you to create a pretty website for your package without any big effort.</p>
<p>How does one use it? After installing it, run <code>pkgdown::init()</code> and <code>pkgdown::build_site()</code> at the root of your package. This will create a docs/ folder containing the static html documentation, that you can browse locally.</p>
<p>Now, how do you present it to the world? In theory I guess you could publish it anywhere but the really handy thing is to have it as a Github page, if you develop your package on Github. For this you just need to change the settings of the repository to make master/docs the source for Github pages.</p>
<p><img alt="" src="https://i2.wp.com/maelle.github.io/figure/source/2017-06-17-automatictools/gh.png?w=456" data-recalc-dims="1"></p>
<p>Unless you typically redirect all links from your Github account to your domain, your package will live at account_name.github.io/package_name. See for instance <a rel="nofollow" href="https://github.com/dirkschumacher/ompr" target="_blank">this nice package of Dirk Schumacher’s</a> whose website is <a rel="nofollow" href="https://dirkschumacher.github.io/ompr/" target="_blank">here</a>.</p>
<h2>How to customize the website?</h2>
<p>This part is not automatic, and demands creating a <code>_pkgdown.yml</code> file at the root of your package. I’ve only mentioned two aspects:</p>
<ul>
<li>
<p>One can change the style of the website, e.g. <a rel="nofollow" href="https://github.com/maelle/rtimicropem/blob/master/_pkgdown.yml" target="_blank">in this config file</a> I chose another Boostrap theme than the default one. To choose one Boostrap theme one can browse them online or look at a pkgdown website that one likes and look at how it was created. A participant of the meetup told me that there is an RStudio addin for choosing a theme but I couldn’t locate it.</p>
</li>
<li>
<p>One can change the order of vignettes, or of the functions, and even group them, which might be extremely useful when a package has many functions. Usually the alphabetical order makes little sense. See <a rel="nofollow" href="https://github.com/dirkschumacher/ompr/blob/master/_pkgdown.yml" target="_blank">here</a> the config file of <a rel="nofollow" href="https://dirkschumacher.github.io/ompr/" target="_blank">this website</a>, the grouping is really well done.</p>
</li>
</ul>
<h1>Conclusion</h1>
<p>Since this was a talk, not a long workshop, and also because I don’t know everything, I have not mentioned every useful tool in the world. I’d be grateful for suggestions in the comments, and in the meantime here are some tools I briefly mentioned at the end of my talk:</p>
<ul>
<li>
<p>Continuous integration, with this <a rel="nofollow" href="https://juliasilge.com/blog/beginners-guide-to-travis/" target="_blank">well written post by Julia Silge</a></p>
</li>
<li>
<p>The <a rel="nofollow" href="https://github.com/r-hub" target="_blank">R-hub project</a></p>
</li>
<li>
<p>The <a rel="nofollow" href="https://github.com/ropensci/PackageDevelopment" target="_blank">CRAN task view about package development</a></p>
</li>
<li>
<p>The <a rel="nofollow" href="https://github.com/ropenscilabs/available" target="_blank"><code>available</code> package</a> to check whether the name you want to use for your package is a) available and b) appropriate.</p>
</li>
</ul>
<p>A very important tip I gave was to have your code read by humans. The automatic tools will flag some things, but the feedback of an human about your code and your documentation will be crucial. And when <em>you</em> review code, you’ll learn a lot! If you want to do that, you can volunteer to become a reviewer for rOpenSci, see more info <a rel="nofollow" href="https://github.com/ropensci/onboarding#why-review" target="_blank">here</a> and fill the short form <a rel="nofollow" href="https://ropensci.org/onboarding/" target="_blank">here.</a></p>
<p><img alt="" src="https://i1.wp.com/maelle.github.io/figure/source/2017-06-17-automatictools/tshirt.jpeg?w=456" data-recalc-dims="1"><br>
After my talk I got a nice RMarkdown t-shirt that has the same colour as my face! Thanks a lot to the organizers, in particular Luca Cerone!</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://maelle.github.io/2017/06/17/automatictools/"> Maëlle</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/jS5SawUFsoE" height="1"></a></div>