<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/a-dirty-hack-for-importing-packages-that-use-depends-2/"></div></div><div><a data-url="https://www.r-bloggers.com/a-dirty-hack-for-importing-packages-that-use-depends-2/" data-counturl="https://www.r-bloggers.com/a-dirty-hack-for-importing-packages-that-use-depends-2/" data-count="horizontal" data-text="A dirty hack for importing packages that use Depends" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://r2d2.quartzbio.com/posts/package-depends-dirty-hack-solution.html"> R2D2</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>


<ul>
<li>A dirty hack for importing packages that use Depends</li>
<li><br></li>
<li>2013-05-27</li>
<li><a target="_blank" href="http://r2d2.quartzbio.com/posts/package-depends-dirty-hack-solution.Rmd">Source</a>
</li>
</ul>
<div>
<h2>Scope</h2>
<p>This article is about R package development.</p>
<h2>Motivation</h2>
<p>As stated in the the <em>Writing R Extensions</em> manual and the <em>Software for Data Analysis</em> book (aka the R bible), packages should<br>
whenever possible use <strong>Imports</strong> instead of <strong>Depends</strong>, to avoid name collision (masking) and ensure trustworthy computations.<br>
See <a target="_blank" href="http://stackoverflow.com/questions/8637993/better-explanation-of-when-to-use-imports-depends">this discussion on Stackoverflow</a>.</p>
<h2>The problem</h2>
<p>So after adopting best practices, and only using <strong>Imports</strong> in my packages, the problem is that some <em>imported</em> packages<br>
do not follow those best practices and rely on <strong>Depends</strong> for their dependencies, and consequently will not find<br>
their dependencies unless hacked. </p>
<p>Say we are writing a package <strong>MyPkg</strong>, that uses some functions from a CRAN package <strong>A</strong>, which lists a CRAN<br>
package <strong>B</strong> in its Depends.</p>
<p><em>MyPkg::f</em></p>
<pre><code>f &lt;- function() a()
</code></pre>
<p><em>A::a</em></p>
<pre><code>a &lt;- function() b()
</code></pre>
<p><em>B::b</em><br>
b &lt;- function() { … }</p>
<p>Executing <code>f()</code> will find the function <code>a</code>, explicitly imported from package A. But executing <code>a()</code> will die because<br>
function <code>b</code> can not be found.</p>
<h2>analysis</h2>
<p>Because B is listed in the Depends of package A, <code>b()</code> is normally found in the <em>search path</em>, where namespace <strong>B</strong> is attached.<br>
What can we do to work around this problem ?<br>
Sadly, there is nothing we can do at the <strong>MyPkg</strong> package level, since the problem sits in the <strong>A</strong> namespace.<br>
We could of course lists B in the <strong>MyPkg</strong> Depends, but that is precisely what we want to avoid.</p>
<h2>the dirty hack solution</h2>
<h3>the idea</h3>
<p>I suggest that you first have a look at this very good blog<br>
<a target="_blank" href="http://obeautifulcode.com/R/How-R-Searches-And-Finds-Stuff/">How R Searches and Finds Stuff</a> if you need some<br>
clarification about namespaces and imports. </p>
<p>Here is a diagram of the current state of the problem:</p>
<p><img alt="plot of chunk unnamed-chunk-1" src="https://i1.wp.com/r2d2.quartzbio.com/posts/assets/fig/unnamed-chunk-1-1.png?w=456" data-recalc-dims="1"> </p>
<p>We want the <code>a()</code> call, which is executed in namespace <strong>A</strong>, to find the <strong>b</strong> symbol in namespace <strong>B</strong>.<br>
To achieve this, we will re-route the namespace <strong>A</strong> (actually its Imports namespace) to the <strong>B</strong> namespace:</p>
<pre><code>nsa &lt;- getNamespace('A')                      # package A environment
nsa_imp &lt;- parent.env(nsa)                    # package A Imports
parent.env(nsa_imp) &lt;- getNamespace('B')      # re-route A Imports to package B
</code></pre>
<p>Now our namespaces should look like this: </p>
<p><img alt="plot of chunk unnamed-chunk-2" src="https://i0.wp.com/r2d2.quartzbio.com/posts/assets/fig/unnamed-chunk-2-1.png?w=456" data-recalc-dims="1"> </p>
<p>Notice that the link From A Imports to base has been re-routed towards package B (the arrow labelled &quot;New&quot;)</p>
<h2>Example</h2>
<p>The above code is not straightforward to test because you need to write a package. </p>
<p>Here is some reproducible code that illustrates how the hack works, so that you can simulate its mechanism<br>
right now by copy-pasting the following code in your R console.<br>
This example uses package <strong>multcomp</strong> that <em>Depends</em> on <strong>mvtnorm</strong>. </p>
<pre><code>## load multcomp package, and its imports, but do not attach them in the search path
l &lt;- loadNamespace('multcomp') # assignment to avoid annoying print

amod &lt;- aov(breaks ~ wool + tension, data = warpbreaks)
wht &lt;- multcomp::glht(amod, linfct = multcomp::mcp(tension = &quot;Tukey&quot;))
ci &lt;- confint(wht) # mvtnorm::qmvt is not found, because mvtnorm is not attached to the search path

# let's load the mvtnorm namespace 
l &lt;- loadNamespace('mvtnorm')
ci &lt;- confint(wht) # mvtnorm::qmvt still not found, mvtnorm is loaded but not attached

# hack hack hack: re-route package multcomp to mvtnorm
ns1 &lt;- getNamespace('multcomp')
ns1_imp &lt;- parent.env(ns1)
parent.env(ns1_imp) &lt;- getNamespace('mvtnorm')

ci &lt;- confint(wht) # now should work
print(ci)
</code></pre>
<pre><code>## 
##   Simultaneous Confidence Intervals
## 
## Multiple Comparisons of Means: Tukey Contrasts
## 
## 
## Fit: aov(formula = breaks ~ wool + tension, data = warpbreaks)
## 
## Quantile = 2.4162
## 95% family-wise confidence level
##  
## 
## Linear Hypotheses:
##            Estimate lwr      upr     
## M - L == 0 -10.0000 -19.3563  -0.6437
## H - L == 0 -14.7222 -24.0785  -5.3659
## H - M == 0  -4.7222 -14.0785   4.6341
</code></pre>
<h2>implementation of the hack in MyPkg</h2>
<p>Just put the re-routing code in your MyPkg <strong>.onLoad</strong> function, defined usually in <code>R/zzz.R</code>:</p>
<pre><code>.onLoad &lt;- function(libname, pkgname) {
    nsa &lt;- getNamespace('A')
    nsa_imp &lt;- parent.env(nsa)
    parent.env(nsa_imp) &lt;- getNamespace('B')    
}
</code></pre>
<h3>why dirty ?</h3>
<p>First of all, it uses <code>parent.env&lt;-</code>, and according to the documentation:</p>
<blockquote>
<p>The replacement function parent.env&lt;- is extremely dangerous as it can be used to destructively change environments in ways >that violate assumptions made by the internal C code. It may be removed in the near future.</p>
</blockquote>
<p>It is a pity because it can be extremely useful.</p>
<h3>why a hack ?</h3>
<p>Unfortunately it does not work in the general case.<br>
Suppose you need two packages A and D, that both depend on B and C, but with different rules:</p>
<pre><code>A -> B -> C
D -> C -> B
</code></pre>
<p>In that case, we would re-route A to B, then B to C. And this is incompatible with the way D is designed, resulting in<br>
wrong symbol picks if symbols with same name are both defined by B and C.</p>
<h3>so what ?</h3>
<p>We'll see in a future post a probably much better solution.</p>
<p><em>Karl Forner @ Quartz Bio</em></p>
</div>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="https://www.r-bloggers.com/a-dirty-hack-for-importing-packages-that-use-depends-2/"></div></div><div><a data-url="https://www.r-bloggers.com/a-dirty-hack-for-importing-packages-that-use-depends-2/" data-counturl="https://www.r-bloggers.com/a-dirty-hack-for-importing-packages-that-use-depends-2/" data-count="vertical" data-text="A dirty hack for importing packages that use Depends" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://r2d2.quartzbio.com/posts/package-depends-dirty-hack-solution.html"> R2D2</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 title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/DyOcf9kpfYo"></a></div>