5

Why do I have this error message :

> vegan::reorder.hclust
Error: 'reorder.hclust' is not an exported object from 'namespace:vegan'

While this S3 method is well available. For example if I type help(reorder.hclust, package = "vegan") I obtain the intended help page and vegan:::reorder.hclust displays the source code of the function on the console...
Also the NAMESPACE file of my vegan installation contains S3method(reorder, hclust).

I would like to use this function in another package were I need to import it or use vegan::reorder.hclust

> sessionInfo()
R version 3.4.3 (2017-11-30)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 16.04.4 LTS

Matrix products: default
BLAS: /usr/lib/libblas/libblas.so.3.6.0
LAPACK: /usr/lib/lapack/liblapack.so.3.6.0

locale:
 [1] LC_CTYPE=fr_BE.UTF-8       LC_NUMERIC=C               LC_TIME=fr_BE.UTF-8       
 [4] LC_COLLATE=fr_BE.UTF-8     LC_MONETARY=fr_BE.UTF-8    LC_MESSAGES=fr_BE.UTF-8   
 [7] LC_PAPER=fr_BE.UTF-8       LC_NAME=C                  LC_ADDRESS=C              
[10] LC_TELEPHONE=C             LC_MEASUREMENT=fr_BE.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] MASS_7.3-49     compiler_3.4.3  Matrix_1.2-11   parallel_3.4.3  tools_3.4.3    
 [6] mgcv_1.8-23     yaml_2.1.18     nlme_3.1-131.1  grid_3.4.3      permute_0.9-4  
[11] vegan_2.4-6     cluster_2.0.6   lattice_0.20-35
Gilles San Martin
  • 4,224
  • 1
  • 18
  • 31

1 Answers1

3

You get that error because vegan doesn't export that function. It can give help for things that aren't exported. Using three colons vegan:::reorder.hclust displays internal functions that are not exported; normally you should avoid using those.

However, when the vegan package is loaded, its reorder.hclust function will be added to the methods table for reorder. So you just need to make sure that it is loaded, and then if hc is an hclust object, reorder(hc) will call the reorder.hclust method. You can do this by putting requireNamespace("vegan") into your code, or importing something from vegan in your NAMESPACE file.

If there are two reorder.hclust methods (defined by different packages that are both loaded), then I don't think there's an easy way for you to specify the vegan one other than using vegan:::reorder.hclust, which CRAN will object to. You would need to ask the vegan maintainer to export their function so you could access it using the legal vegan::reorder.hclust, or copy the code into your own package, or some other inconvenient approach.

user2554330
  • 37,248
  • 4
  • 43
  • 90
  • 1
    `utils::getFromNamespace("reorder.hclust", "vegan")` is one approach to use the function and pass CRAN test. – missuse Mar 16 '18 at 11:21
  • The docs warn against using `getFromNamespace`: "should not be used in production code". So CRAN may add this to its tests later. – user2554330 Mar 16 '18 at 11:27
  • Thanks for the answer ! Something I don't understand : isn't `S3method(reorder, hclust)` the way to export it from vegan (this is in the NAMESPACE file of the package) ? – Gilles San Martin Mar 16 '18 at 11:35
  • To summarize : 3 solutions for the moment : 1) contact the vegan developer to ask him to export the function (but how if `S3method(reorder, hclust)` is not the way to do that ?), 2) copy the code in my package (not very nice - this is what I do for the moment) 3) according to the answer in the similar question pointed by @RolandASc : add `Depends: vegan` in the DESCRIPTION of my package to force this package to be attached (not very nice either). And maybe also ( use `utils::getFromNamespace("reorder.hclust", "vegan")` but this does not seem to be recommended. – Gilles San Martin Mar 16 '18 at 11:43
  • **vegan** *exports* that function, but you did not use it appropriately. If you have a method function like `reorder.hclust`, you should use it as `reorder()`, but it won't work when used as `reorder.hclust()`. This also holds for any other **vegan** S3 method function: for instance, `plot.cca()` will fail, but `plot()` will work. – Jari Oksanen Mar 16 '18 at 12:58
  • R has a fairly complicated model for scoping. The `S3method` declaration in NAMESPACE *only* adds that method to the `reorder` method table, which is not the same as exporting it. Code outside of `vegan` can't see the function unless it uses `:::` or `getFromNamespace`, or the code is the generic using that method table. – user2554330 Mar 16 '18 at 14:02
  • Thanks for your additional comments. @Jari Oksanen : I have been using this `reorder` methods for `hclust` objects as you recommend for years (by the way thanks for these very useful function you developed that should indeed be in base R...). Now that I want to embed my functions in a package I struggle to import the `reorder.hclust` method in my package... So I tried different possibilities. I don't see how I can import this function otherwise. I don't understand neither why the `S3method(reorder, hclust)` code you used in `NAMESPACE` seem to be not enough to let me import it. – Gilles San Martin Mar 16 '18 at 16:11
  • Why not call it the way Jari and I have suggested, i.e. as `reorder(hc)`? – user2554330 Mar 16 '18 at 17:14
  • @user2554330 : It seems not possible to use `reorder(hc)` in my package unless I attach the whole `vegan` package either by an explicit call to `library(vegan)` within the code of my package (which is what I do in a local R script) or by adding `Depends: vegan` in the DESCRIPTION of my package. I read that attaching a whole external package seems to be not generally recommended in package development (eg because it modifies the search path of the user and increases the risk of conflicts). – Gilles San Martin Mar 16 '18 at 17:26
  • What about the suggestions in my answer, `requireNamespace` or importing something from `vegan`? By the way, you should also look at the `getS3method` function, which probably does what you want. – user2554330 Mar 16 '18 at 18:56
  • Adding `requireNamespace(vegan, quitely = TRUE)` in my package package function then `reorder(hcl_object)` indeed works ! It loads the package without attaching it (as `vegan::reorder` would do if it worked and if I understand well how all this works). I have tried Importing from`vegan` in my `NAMESPACE` file (eg `importFrom("vegan", "reorder.hclust")`) without success... `getS3method` works only if vegan is attached but not if it is only loaded ! Thanks again for your help and patience ! – Gilles San Martin Mar 16 '18 at 21:55
  • 1
    Just two followups: the double dot notation *does not* cause the package to become attached, only loaded. It only works on functions exported from the package. So `vegan::vegdist` would trigger loading of the package if it is installed. Similarly, `importFrom("vegan", "vegdist")` would work to get it loaded, but you can't import something like `reorder.hclust` because it was not exported. – user2554330 Mar 18 '18 at 19:29
  • I am preparing a new **vegan** release next week. I could export `reorder.hclust` if you have a serious need and think it is the best way to go. What kind of need do you have? – Jari Oksanen Mar 28 '18 at 06:32