6

I have a package which uses the tmPlot function from treemap, but when I try to use the function, it throws an error that one of its dependencies isn't loaded:

Error in tmPlot(data, index = index, vSize = vSize) : 
  could not find function "brewer.pal"

The dependency is installed and in the namespace.

This question has a little bit of setup, being a package problem, but I've tried to make it as minimal as possible:

Ensure you have treemap (and all its dependencies) installed.

I've made a directory called 'anRpackage'. Inside it is a folder ('R') and a DESCRIPTION file with the following text:

Package: anRpackage
Title: What the package does (short line)
Version: 1.0
Author: Who wrote it
Maintainer: Who to complain to <yourfault@somewhere.net>
Description: More about what it does (maybe more than one line)
License: What license is it under?
Imports:
    treemap
Collate:
    'maketree.R'

Inside the R/ folder is a single R file called 'maketree.R'. Its contents are:

#' maketree
#' 
#' @importFrom treemap tmPlot
#' @export maketree

maketree <-
function(data, index, vSize){
  tmPlot(data, index=index, vSize=vSize)
}

Assuming you're in the directory above 'anRpackage', run the following script:

library(roxygen2)
roxygenise("anRpackage/")

library(devtools)

build("anRpackage")
install("anRpackage")

Restart R (preferably with --vanilla) and run the following:

library(anRpackage)

data(mtcars)
maketree(mtcars, "cyl", "mpg")

You should get the error I described right at the beginning. Why does this happen? RColorBrewer is listed as Depends for treemap, so it should be be automatically imported, should it not?

sebastian-c
  • 15,057
  • 3
  • 47
  • 93
  • Try adding `import RColorBrewer`. This package may not be loaded automatically by `treemap` or maybe it does but calling just the one function from tree map doesn't call `RColorBrewer`. – Tyler Rinker Feb 11 '13 at 09:07
  • 1
    @TylerRinker It's not so much that I want any fix for the problem (the problem can easily be fixed by adding `library(treemap)` in the function). It's more that I want to know why this problem is happening here when, by my understanding, it should not happen. I don't understand why some packages need to be loaded manually and not others. – sebastian-c Feb 11 '13 at 10:26

3 Answers3

10

The problem is really with treemap. treemap uses brewer.pal, and so should Imports: RColorBrewer and importFrom(RColorBrewer, brewer.pal).

As it stands now, everything is ok if the user says library(treemap), treemap and RColorBrewer are attached to the search() path, and when tmPlot is evaluated brewer.pal is found on the search path. Of course the package would break if the user were to say brewer.pal="yeast" or something, because the wrong symbol would be found; this is one of the reasons for a name space, to protect treemap's functions from what the user might do.

But what happens when you (correctly) Imports: treemap? treemap is loaded (into memory) but neither treemap nor its dependencies are attached (to the search path). So brewer.pal is not found.

If treemap were to Imports: RColorBrewer, then brewer.pal would be found both when treemap were attached to the search path by a call to library(treemap), and when only imported into your package.

Contact the maintainer of treemap and ask them to do a more careful job of constructing their name space.

Martin Morgan
  • 45,935
  • 7
  • 84
  • 112
  • 2
    Very nicely explained. I need to contact a couple of package maintainers with just this request, and wonder if there's a canonical document to point them to -- something particularly good in the R docs, on the CRAN website, or the R-devel list-serve. Now I may just use your answer instead. Thanks. – Josh O'Brien Feb 11 '13 at 14:09
  • Agreed, nice explanation +1 – Tyler Rinker Feb 11 '13 at 15:05
  • So is the main problem that they're using Depends rather than Imports or that their NAMESPACE is missing the appropriate statements? – sebastian-c Feb 11 '13 at 23:56
  • @sebastian-c For this particular issue, treemap should be using Imports: RColorBrewer in DESCRIPTION (and probably not Depends: RColorBrewer -- treemap end-users do not need to use RColorBrewer functions directly), and adding importFrom(RColorBrewer, brewer.pal) to their NAMESPACE. From a quick glance there are additional packages / symbols that should be imported. – Martin Morgan Feb 12 '13 at 00:14
  • 1
    @MartinMorgan I contacted the author of the package and he informs me that this is to be fixed in the next release. – sebastian-c Feb 12 '13 at 07:45
1

before calling the tmPlot(data, index = index, vSize = vSize), you need to load RColorBrewer:

require(RColorBrewer)
Néstor Waldyd
  • 924
  • 7
  • 6
0

I think it's due to the fact that you use Imports instead of Depends in your DESCRIPTION file.

If you use Depends: treemap, the treemap package is loaded and attached when you load your package, and as such the treemap dependencies are loaded too.

If you use Imports: treemap, then only the specified namespace is imported, ie you can use the treemap variables in your functions. But it seems that in this case the treemap dependencies are not loaded.

So I think you should either use Depends: treemap (but it seems that the use of Imports is promoted these days), or import RColorBrewer directly from your package.

Sorry, not sure this really answers your question, and you may be already perfectly aware of all of these points...

juba
  • 47,631
  • 14
  • 113
  • 118