<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/whats-inside-pkginspector-provides-helpful-tools-for-inspecting-package-contents/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://ropensci.org/blog/2018/07/17/pkginspector/"> rOpenSci - open tools for open science</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p><p><center><br>
<img alt="pkginspector hex sticker" src="https://i2.wp.com/ropensci.org/blog/2018/07/17/pkginspector/img/blog-images/2018-07-17-pkginspector/pkginspector_hex_sticker.png?w=456&ssl=1" data-recalc-dims="1"><br>
</center></p>
<p>R packages are widely used in science, yet the code behind them often does not come under scrutiny. To address this lack, rOpenSci has been a pioneer in developing a peer review process for R packages. The goal of <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/" target="_blank"><code>pkginspector</code></a> is to help that process by providing a means to better understand the internal structure of R packages. It offers tools to analyze and visualize the relationship among functions within a package, and to report whether or not functions’ interfaces are consistent. If you are reviewing an R package (maybe your own!), <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/" target="_blank"><code>pkginspector</code></a> is for you.</p>
<p>We began building <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/" target="_blank"><code>pkginspector</code></a> during <a rel="nofollow" href="http://unconf18.ropensci.org/" target="_blank">unconf18</a>, with support from <a rel="nofollow" href="https://ropensci.org/" target="_blank">rOpenSci</a> and guidance from <a rel="nofollow" href="https://github.com/noamross" target="_blank">Noam Ross</a>. The package focuses on facilitating a few of the many tasks involved in reviewing a package; it is one of a collection of packages, including <a rel="nofollow" href="https://github.com/ropenscilabs/pkgreviewr" target="_blank"><code>pkgreviewr</code></a> (rOpenSci) and <a rel="nofollow" href="https://github.com/MangoTheCat/goodpractice" target="_blank"><code>goodpractice</code></a>, among others, that are devoted to this project. (The division of labor among these packages is <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/issues/18" target="_blank">under discussion</a>). If you’re not familiar with rOpenSci’s package review process, <a rel="nofollow" href="https://ropensci.org/blog/2017/09/01/nf-softwarereview/" target="_blank">“How rOpenSci uses Code Review to Promote Reproducible Science”</a> provides context.</p>
<p></p>
<h3>Function calls</h3>
<p><code>rev_fn_summary()</code> helps you analyze function calls. It takes a package path and returns a table of information about its functions. Consider this example included in <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/" target="_blank"><code>pkginspector</code></a>:</p>
<pre><code># devtools::install_github(&quot;ropenscilabs/pkginspector&quot;)
library(pkginspector)
path &lt;- pkginspector_example(&quot;viridisLite&quot;)
rev_fn_summary(path)
</code></pre>
<pre><code>##       f_name
## 1    cividis
## 2    inferno
## 3      magma
## 4     plasma
## 5    viridis
## 6 viridisMap
##                                                                     f_args
## 1               cividis (n, alpha = 1, begin = 0, end = 1, direction = 1) 
## 2               inferno (n, alpha = 1, begin = 0, end = 1, direction = 1) 
## 3                 magma (n, alpha = 1, begin = 0, end = 1, direction = 1) 
## 4                plasma (n, alpha = 1, begin = 0, end = 1, direction = 1) 
## 5 viridis (n, alpha = 1, begin = 0, end = 1, direction = 1, option = &quot;D&quot;) 
## 6      viridisMap (n = 256, alpha = 1, begin = 0, end = 1, direction = 1, 
##   calls called_by dependents
## 1     1         0          0
## 2     1         0          0
## 3     1         0          0
## 4     1         0          0
## 5     0         4          4
## 6     0         0          0
</code></pre>
<p>The example shows that the number of functions called by <code>cividis()</code>, <code>inferno()</code>, <code>magma()</code> and <code>plasma()</code> is 1, 1, 1 and 1, and that these functions are called by 0, 0, 0 and 0 functions. <code>viridis()</code>, in contrast, calls 0 functions but is called by 4 functions. In this case, the number of <code>dependents</code> is 4. Dependents are counted recursively and include any functions in the calling chain. For example, if A calls B and B calls C, we would say that C is called by 1 (B) but has 2 dependents (A &amp; B). <code>rev_fn_summary()</code> also provides information about function parameters in the <code>f_args</code> column.</p>
<p><em>What’s not working:</em> We know that we miss function calls if they are passed as parameters to <code>purrr::map()</code> and <code>do.call()</code> functions. There may be other systematic misses as well.</p>
<p></p>
<h3>Visualization</h3>
<p><code>vis_package()</code> helps you visualize the network of functions’ dependencies (<a rel="nofollow" href="http://rpubs.com/jtr13/vis_package" target="_blank">interactive example</a>).</p>
<pre><code>vis_package(path, physics = FALSE)
</code></pre>
<p><img alt="vis_package screenshot" src="https://i2.wp.com/ropensci.org/blog/2018/07/17/pkginspector/img/blog-images/2018-07-17-pkginspector/viridisLite.png?w=456&ssl=1" data-recalc-dims="1"></p>
<h3>Argument default usage</h3>
<p><code>rev_args()</code> identifies all the functions’ arguments used in a given package. It returns a dataframe whose main column, <code>default_consistent</code>, indicates whether or not the default value of the argument is consistent across the functions that use it. This helps to evaluate the complexity of the package and to identify potential sources of confusion, for example, if the meaning or default value of the same argument varies across functions.</p>
<pre><code>rev_args(path)$arg_df
</code></pre>
<pre><code>##    arg_name n_functions default_consistent default_consistent_percent
## 1         n           6              FALSE                   83.33333
## 2     alpha           6               TRUE                  100.00000
## 3     begin           6               TRUE                  100.00000
## 4       end           6               TRUE                  100.00000
## 5 direction           6               TRUE                  100.00000
## 6    option           2               TRUE                  100.00000
</code></pre>
<p>The example shows that the parameter <code>n</code> is used inconsistently. A look at the <a rel="nofollow" href="https://github.com/sjmgarnier/viridisLite/blob/master/R/viridis.R" target="_blank"><code>viridisLite</code> code</a> reveals that the default value of <code>n</code> is 256 in one function but missing in all others. This flags a potential issue that deserves further investigation. In this case, the odd function out – <code>viridisMap()</code> – has a clear use case that is different from the others.</p>
<p></p>
<h3>In sum</h3>
<p>If you are building or reviewing an R package, <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/" target="_blank"><code>pkginspector</code></a> can help you better understand its complex structure. This is an important step towards improving your code and research. While <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/" target="_blank"><code>pkginspector</code></a> will expand in scope, the features built during and since unconf18 are already useful. For example, if you’ve tried sketching out the relationship among functions in a package with pencil and paper, you will appreciate the ability to call <code>vis_package()</code> to create a network diagram.</p>
<p>Our broader vision for <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/" target="_blank"><code>pkginspector</code></a> is a tool that guides both the development and review of R packages and provides automated checks on subtle differences in package functions that inevitably arise during the development process. The package will (hopefully) grow and exist as a living toolbox for development and review. If you have ideas for tools that could be added to <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/" target="_blank"><code>pkginspector</code></a> to facilitate the process of reviewing a package, we encourage you to open an <a rel="nofollow" href="https://github.com/ropenscilabs/pkginspector/issues" target="_blank">issue</a>.</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="https://ropensci.org/blog/2018/07/17/pkginspector/"> rOpenSci - open tools for open science</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/6H_z7OF04MA" height="1"></a></div>