[R] On-demand importing of a package

Martin Morgan mtmorgan at fhcrc.org
Wed Nov 23 00:57:23 CET 2011


On 11/22/2011 03:06 PM, Gábor Csárdi wrote:
> On Tue, Nov 22, 2011 at 4:27 PM, Martin Morgan<mtmorgan at fhcrc.org>  wrote:
> [...]
>> No need to Depend:. Use
>>
>> Imports: Matrix
>>
>> plus in the NAMESPACE file
>>
>>   importFrom(Matrix, rowSums)
>>
>> Why do you not want to do this? Matrix is available for everyone, Imports:
>> doesn't influence the package search path. There is a cost associated with
>> loading the library in the first place, but...?
>
> Not just loading, installing a package has a cost, too. Dependencies
> are bad, they might make my package fail, and I have no control over
> them. It's not just 'Matrix', I have this issue with other packages as
> well.
>
> Anyway, 'Imports: Matrix' is just a workaround I think. Or is the
> example in my initial mail expected to fail? Why is that? Why can I
> call some functions from 'Matrix' that way and why can't I call
> others?
>
>> I'm more into black-and-white -- it either needs Matrix or not; apparently
>> it does.
>
> It's a matter of opinion, I guess. I find it very annoying when I need
> to install a bunch of packages from which I don't use any code, just
> because some tiny bit of a package I need uses them. I would like to
> spare my users from this.
>
> [...]
>> In another message you mention
>>
>>> Matrix:::rowSums(W)
>> Error in callGeneric() :
>>   'callGeneric' must be called from a generic function or method
>>
>> but something else is going on -- you don't get to call methods directly;
>> you're getting Matrix::rowSums (it's exported, so no need for a :::, see
>> getNamespaceExports("Matrix")). Maybe traceback() after the error would be
>> insightful?
>
> Another poster suggested this, that's why I tried. It is clear that I
> should not call it directly. All I want to do is having a function
> like this:
>
> f<- function() {
>   if (require(Matrix)) {
>     res<- sparseMatrix(dims=c(5, 5), i=1:5, j=1:5, x=1:5)
>   } else {
>     res<- diag(1:5)
>   }
>   y<- rowSums(res)
>   res / y
> }
>
> Setting the subjective bit, about depending or not, aside, is there
> really no solution for this? The code in the manual page examples work
> fine without importing the package and just loading it if needed and
> available. Why doesn't the code within the package?

If I create a package that does not Import: Matrix (btw, Matrix is 
distributed with all R), with only a function f, and with exports(f) in 
NAMESPACE, I get

 > library(pkgA)
 > f()
Loading required package: Matrix
Loading required package: lattice

Attaching package: 'Matrix'

The following object(s) are masked from 'package:base':

     det

Error in rowSums(res) : 'x' must be an array of at least two dimensions

This is because (a) Matrix is attached to the user search path but (b) 
because f is defined in the NAMESPACE of pkgA, rowSums is looked for 
first in the pkgA NAMESPACE, and in then in the search of the package 
(which includes base) and then in the user search path. It is found in 
base, and the search ends there.

If I modify f to use  y <- Matrix::rowSums(res) I get

 > f()
Loading required package: Matrix
Loading required package: lattice

Attaching package: 'Matrix'

The following object(s) are masked from 'package:base':

     det

5 x 5 sparse Matrix of class "dgCMatrix"

[1,] 1 . . . .
[2,] . 1 . . .
[3,] . . 1 . .
[4,] . . . 1 .
[5,] . . . . 1

I start off with the correct rowSums, and continue from there.

Martin

>
> Thanks for the patience,
> Gabor
>
>> Martin
>>
> [...]
>


-- 
Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

Location: M1-B861
Telephone: 206 667-2793



More information about the R-help mailing list