Skip to content

Re R CMD check checking in development version of R

22 messages · Dan Tenenbaum, Uwe Ligges, Martin Morgan +9 more

#
Dear list,

This is related to the change discussed in the thread "no visible binding
for global variables for data sets in a package".

I went to look at the Check results for one of my packages (analogue) on
CRAN: http://cran.r-project.org/web/checks/check_results_analogue.html

Under the r-devel build machines I'm seeing a lot of things like this:

    Stratiplot.default : axis.VarLabs: no visible global function
     definition for ?current.panel.limits?
    Stratiplot.default : axis.VarLabs: no visible global function
     definition for ?panel.axis?
    Stratiplot.default : axis.VarLabs: no visible global function
     definition for ?which.packet?
    Stratiplot.default : axis.VarLabs: no visible global function
     definition for ?axis.default?
    Stratiplot.default: no visible global function definition for ?xyplot?
    Stratiplot.default: no visible binding for global variable
     ?axis.default?
    initCurve: no visible global function definition for ?cca?
    initCurve: no visible global function definition for ?rda?
    oldDistance.default: no visible global function definition for
     ?vegdist?
    panel.Loess: no visible global function definition for
     ?trellis.par.get?
....
    panel.Stratiplot: no visible global function definition for
     ?panel.abline?
    plot3d.prcurve: no visible global function definition for ?rda?
    prcurve: no visible global function definition for ?rda?
    tran.default: no visible global function definition for ?wisconsin?
    tran.default: no visible global function definition for ?decostand?

I realise that I don't importFrom all of those functions in NAMESPACE -
I've missed some so this list is actually very handy. But also I Depend on
packages that provide some of the function complained about.

Is that the cause of these NOTEs? Is the expectation that if I am using a
function from a package, even a package that I have in Depends:, that I
have to explicitly declare these imports in NAMESPACE?

I'm just seeking a bit of clarification on what this new check aims to test
and what is the ideal solution in the view of R Core given this change to R
CMD check.

Thanks in advance

Gavin
#
Yes.

(Otherwise your package won't work if it's only attached and not
loaded. i.e. if someone does analogue::foo() only the imported
functions are available, not the functions in packages you depend on)

(And really you shouldn't have any packages in depends, they should
all be in imports)

Hadley
#
On 27 August 2014 15:24, Hadley Wickham <h.wickham at gmail.com> wrote:

            
Cheers Hadley. Thanks for the confirmation, but...

...I don't get this; what is the point of Depends? I thought it was "my
package needs these other packages to work, i.e. be loaded". Hence it is
user error (IMHO ;-) to do `analogue::foo()` without having the
dependencies loaded too.

This check (whilst having found some things I should have imported and
didn't - which is a good thing!) seems to be circumventing the intention of
having something in Depends. Is Depends going to go away?
I disagree with *any*; having say vegan loaded when one is using analogue
is a design decision as the latter borrows heavily from and builds upon
vegan. In general I have moved packages that didn't need to be in Depends
into Imports; in the version I am currently doing final tweaks on before it
goes to CRAN I have remove all but vegan from Depends.

Or am I thinking about this in the wrong way?

Thanks again

Gavin

  
    
#
----- Original Message -----
I've found that if yourpkg (which Depends on theirpkg but does not import it) has yourfunction() which calls some function in theirpkg, and if someone else writes a package which imports yourpkg and calls yourfunction, it will not work. Whereas if yourpkg imported theirpkg (in the NAMESPACE file), it would work. I've had to write to many package maintainers asking them to import things for this reason.

So that in itself is a reason not to use Depends, or at least, to be sure that you import (in your NAMESPACE) whatever's in Depends (in addition to Imports).

Dan
#
On 27 August 2014 16:09, Dan Tenenbaum <dtenenba at fhcrc.org> wrote:

            
Dan,

I think we'll just have to differ on this point Dan. Why should I make it
somewhat more complicated for the people I anticipate using my package just
so that I make it easier for developers of other packages to *potentially*
write code using my packages. analogue and vegan have been around for a
long time, since before the required namespaces --- in vegan's case
possibly before there were namespaces in R (or at least before the were in
widespread use), so to change the standard behaviour of loading my package
and getting vegan too is not something I'm going to do lightly. Especially
as there are several papers out there with code written before the
compulsory namespace stuff came to R that assumed vegan was loaded because
thats what `library("analogue")` *did*.

I'm happy to work with developers on issues as they arrive of course. I
just don;t see why their envisioned future needs should trump the needs of
the user now.

If we take your and Hadley's reasoning to the extreme, not a single package
should use Depends in which case what purpose is there for Depends? Until R
Core remove Depends from DESCRIPTION and flag it under `R CMD check`-ing
people, including me, are going to continue using it if that is what they
think is best for their users.

Again, I am happy to be re-educated on this though :-)

Cheers,

G

  
    
#
On 28.08.2014 00:19, Gavin Simpson wrote:
If you like, you can fill the search path with lots of packages (and 
make masking of functions more likely), but you shoudl really import 
into your namesoace so that unanticipated order of packages in your 
search path won't break your package.

Best,
Uwe Ligges
#
On 27 August 2014 16:25, Uwe Ligges <ligges at statistik.tu-dortmund.de> wrote:
<snip />
I do already do that (well, I had missed a few which R-devel CMD check
showed to me). I have a corresponding importFrom(vegan, ....) in my
NAMESPACE even with Depends: vegan in DESCRIPTION.

What I'm pushing back on is the notion that *no* packages should be in
Depends.

Cheers,

G
#
On Wed, Aug 27, 2014 at 5:01 PM, Gavin Simpson <ucfagls at gmail.com> wrote:
I'd say: Depends is a historical artefact from ye old days before
package namespaces. Apart from depending on a specific version of R,
you should basically never use depends.  (The one exception is, as
mentioned in R-exts, if you're writing something like latticeExtras
that doesn't make sense unless lattice is already loaded).
I don't think it's going to go away anytime soon, but you should
consider it to be largely deprecated and you should avoid it wherever
possible.
I think that is a reasonable use case for depends. Here's the exact
text from R-exts: "Field ?Depends? should nowadays be used rarely,
only for packages which are intended to be put on the search path to
make their facilities available to the end user (and not to the
package itself): for example it makes sense that a user of package
latticeExtra would want the functions of package lattice made
available."

Personally I avoid even this use, requiring users of my packages to be
explicit about exactly what packages are on the search path.  You are
of course welcome to your own approach, but I think you'll find it
will become more and more difficult to maintain in time. I recommend
that you bite the bullet now.

Put another way, packages should be extremely conservative about
global side effects (and modifying the search path is such a
side-effect)

Hadley
#
On Aug 27, 2014 5:24 PM, "Hadley Wickham"
<snip />
Keeping this nuance in mind when when discussing Depends vs Imports is
important so as to not suggest that there isn't any reason to use Depends
any longer.

I am in full agreement that its use should be limited to exceptional
situations, and have modified my packages accordingly.

Cheers,

G
intention of
analogue is
vegan.
goes

  
  
#
On 08/27/2014 08:33 PM, Gavin Simpson wrote:
A common case in Bioconductor is that a package defines a class and methods 
intended for the user; this requires the package to be on the search path (else 
the user wouldn't be able to do anything with the returned object). A class and 
supporting methods can represent significant infrastructure, so that it makes 
sense to separate these in distinct packages. It is not uncommon to find 3-5 or 
more packages in the Depends: field of derived packages for this reason.

Martin

  
    
#
For that scenario, is it reasonable to say that every package in
depends must also be in imports?

Hadley
#
On 08/28/2014 05:52 AM, Hadley Wickham wrote:
Important to pay attention to capitalization here. A package listed in Depends: 
_never_ needs to be listed in Imports:, but will often be import()'ed (in one 
way or another) in the NAMESPACE. Some would argue that listing a package in 
Depends: and Imports: in this case clarifies intent -- provides functionality 
available to the user, and important for the package itself. Others (such as R 
CMD check) view the replication as redundancy.

I think one can imagine scenarios where a package in the Depends: fields does 
not actually have anything import()'ed, e.g., PkgA defines a class, PkgB 
provides some special functionality that returns the class PkgC use PkgB's 
special functionality without ever manipulating the object of PkgA.

Martin Morgan

  
    
#
On Aug 27, 2014, at 6:01 PM, Gavin Simpson <ucfagls at gmail.com> wrote:

            
No. The point of Depends is that if your package is attached, it also attaches the other packages to make them available for the user. Essentially you're saying "if you want to use my package interactively, you will also want to use those other packages interactively". You still need to use import() to define what exactly is used by your package - as opposed to what you want to be available to the user in case it is attached.

Cheers,
Simon
#
This is a nice explanation of the Imports/Depends distinction. It
ought to go into the Extensions ref manual imho.

Cheers,
Bert

Bert Gunter
Genentech Nonclinical Biostatistics
(650) 467-7374

"Data is not information. Information is not knowledge. And knowledge
is certainly not wisdom."
Clifford Stoll




On Thu, Aug 28, 2014 at 7:39 AM, Simon Urbanek
<simon.urbanek at r-project.org> wrote:
#
Hi,

I second Bert's comment. I would like to go even farther and suggest that it would be really useful if one of the R gurus (like Simon) wrote a relatively non-technical article in the R journal on this topic of "Depends/Imports/Suggested."  Someone like myself would benefit immensely.

Thank you,
Ravi

-----Original Message-----
From: r-devel-bounces at r-project.org [mailto:r-devel-bounces at r-project.org] On Behalf Of Bert Gunter
Sent: Thursday, August 28, 2014 10:47 AM
To: Simon Urbanek
Cc: r-devel at r-project.org
Subject: Re: [Rd] Re R CMD check checking in development version of R

This is a nice explanation of the Imports/Depends distinction. It ought to go into the Extensions ref manual imho.

Cheers,
Bert

Bert Gunter
Genentech Nonclinical Biostatistics
(650) 467-7374

"Data is not information. Information is not knowledge. And knowledge is certainly not wisdom."
Clifford Stoll
On Thu, Aug 28, 2014 at 7:39 AM, Simon Urbanek <simon.urbanek at r-project.org> wrote:
______________________________________________
R-devel at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
#
'Depends' would be 'Attaches'.

...or maybe even 'ImportsAndAttaches' with 'ImportsOnly' (for 'Imports').

I think Simon phrased it very well, and as others already pointed out,
having one package attaching additional ones certainly has its values. This
is probably more useful for packages that are used directly by the end user
than for packages that mainly provides infrastructure to other packages.

Henrik
On Aug 28, 2014 7:48 AM, "Bert Gunter" <gunter.berton at gene.com> wrote:

            

  
  
#
I fully agree.

This is how I have come to understand Depends vs Imports and why I
currently will not be removing vegan from Depends for my analogue package.
This is also why I was pushing back against the notion that was voiced
early in this thread that *nothing* should be in Depends.

Cheers

G
On 28 August 2014 08:47, Bert Gunter <bgunter at gene.com> wrote:

            

  
    
#
Gavin,

I admit to not knowing the details of your package, but do users commonly
need to use symbols from other package *in calls to functions exported by
your package*? If so, you're in the situation Martin (Morgan) described,
which is one I think everyone agrees Depends is appropriate for.

If the above is not the case, and you're arguing it's simply convenient for
users because it's very common for them to use top level functions from
both in the same analysis, the case for Depends is not as strong. In that
case, the official wisdom, AFAIK, is that Depends is not warranted.

~G
On Thu, Aug 28, 2014 at 11:43 AM, Gavin Simpson <ucfagls at gmail.com> wrote:

            

  
    
#
Gabriel,

That is not my understanding of this at all. I could hide the fact that I
was using vegan under the hood, supplying methods for its generics and by
exporting the generic I imported from vegan, etc. But you are missing the
point that I see users of my package, because I envisioned close
interlinking with the functionality provided by vegan, wanting to use vegan
interactively with many of the objects that functions in analogue create.

I do feel this aversion to Depends is being taken too far by some. Simon's
articulation in this thread of what Depends means (to him) is the closest I
have seen to how I have interpreted things. That's also about as close to
official wisdom that I have seen beyond what is in Writing R Extensions.

Analogue also uses Lattice, but I have moved this to Imports as I don't
expect users to be manipulating the few plot alternatives analogue provides
using this graphics package and if they want to they can load lattice
themselves. So, I fully understand the differences and nuances of Depends
and Imports etc. I just don't agree with those that claim no packages
should be in Depends, or that my use case is somehow wrong or not best
practice.

G
On 28 August 2014 15:14, Gabriel Becker <gmbecker at ucdavis.edu> wrote:

            

  
    
#
Gavin,

I don't claim to be the arbiter of good package design. The following are
my opinions, along with the reasons I hold them.

If you are also importing vegan, which I think everyone agreed needs to
happen, the only thing putting vegan in Depends does is attach the package.
This is something users can easily do themselves, and which *may* not be
required to use your package (I don't know). As such, using Depends limits
the user's agency/control over their session in return for what I would
argue may (depending on circumstance) be a nominal benefit at best.

Continued inline.
On Thu, Aug 28, 2014 at 2:42 PM, Gavin Simpson <ucfagls at gmail.com> wrote:

            
Well sure, but if that is the case, they know they want to call functions
in vegan, so I would think that they would expect to load vegan and not
really think twice about having to do so, making your Depends irrelevant.

The other question is, can analogue be used without vegan? If it can,
*forcing* users to have vegan attached it doesn't seem desirable. Depends
gives users less power to avoid or resolve symbol conflicts.

Point in case, there is a logging package called log4r which overrides the
'debug' (madness, I know) symbol, and I once had a package (call it PkgA)
loaded which Depends on log4r it, with good reason, even, since you are
expected to pass a user-created logging object of some kind to the to
PkgA's functions. This meant that the base-R debug function was
*mandatorally* masked. This is very bad for the user (me), and honestly if
the author hadn't agreed to change the Dependency I wouldn't even consider
using the package.

If log4r has been imported, I wouldn't have cared at all, as I would have
been in control of whether the package was attached or not, and when.

I'm sure (hope) that vegan doesn't do anything this egregious, and if not,
your use of Depends isn't The-Most-Horrible-Thing-Ever. I'd argue that it
is undesirable, but relatively mildly so, and others may argue not at all.
If the official wisdom from R-core disagrees with me, that is probably a
good reason not to listen to me. I was under the impression that Depends
was not recommended except in cases like the described by Mr. Morgan.

Best,
~G
On 28 August 2014 15:14, Gabriel Becker <gmbecker at ucdavis.edu> wrote:

            
--

  
    
#
Yes, Depends certainly has a role. The ability of one package to
automatically provide all the facilities of another package to the
user is important. There are many situations where the functionality
you want to provide to the user is split among multiple packages.

For example,

1. xts uses zoo and the user ought to be able to use all the
functionality of zoo when they issue a library(zoo) call.  The
alternatives are that the user must tediously issue library(zoo) every
time they issue library(xts) or else that the zoo code be copied or
partially replicated into xts which would be undesirable
maintenance-wise.

2. Another example is sqldf.  The user wants to be able to use fn$ and
other string manipulation functions in gsubfn when using sqldf in
order to perform string substitution on the SQL statement.  Also its
desirable to be able to directly access sqlite which means the user
needs access to RSQLite.

3. At one time one could just issue library(ggplot2) but now that
ggplot2 does not use Depends for scales one annoyingly needs to issue
library(scales) if one wants to specify a scale.   I use ggplot2
enough that I can remember it despite the ongoing annoyance but I
would hate to think that every package with split functionality
suddenly adds such onerous requirements onto all its users.  (I am not
really picking on ggplot2 which is a very nice package - just this one
aspect.)

I am not sure but there might be additional problems if the secondary
package defines an S3 generic that the primary package needs to use if
one does not use Depends.
On Thu, Aug 28, 2014 at 2:43 PM, Gavin Simpson <ucfagls at gmail.com> wrote:

  
    
#
(Please correct me if I'm wrong. I thought I mostly understood this, 
finally, but I've made the mistake of thinking I understood something 
too many times before.)
On 08/28/2014 10:39 AM, Simon Urbanek wrote:
I agree that "interactively" catches the flavour of what Depends does, 
but technically that is the wrong word. The important point is whether 
the functions in a Depended upon package should be available to the user 
directly without them needing to use library() or require() to make them 
available, in an interactive session or a batch job.
Amplifying a bit: By import() in the NAMESPACE, which you need whether 
you have Depends or Imports in the DESCRIPTION file, you ensure that the 
functions in your package use the ones in the package imported and do 
not get clobbered by anything the user might do. The user might redefine 
functions available to the interactive session, or require() another 
package with functions having the same names, and those are the ones his 
interactive direct calls will find, but your package functions will not 
use those.

People are sure to have differences of opinion about the trade-off 
between the annoyance of having to specifically attach packages being 
used, and the clarity this provides. At first I was really annoyed, but 
have eventually decided I do like the clarity.

In my experience it turns out to be surprisingly rare that you need 
packages in Depends, but there are legitimate cases beyond the annoyance 
case mentioned above. I think if you are putting packages in Depends you 
really do want to have a very good understanding of why you are doing 
that. If you use Depends then you are inviting support difficulties. 
Users will contact you about bugs in the package you attach, even though 
your package may not use the broken functions. If they attach the 
package themselves then they are much more likely to understand who they 
should contact. Core seems to have forgotten to take credit for trying 
to make life easier for package developers.

Paul

as opposed to what you want to be available