[R-pkg-devel] Conditional use of suggested package in example code

Christian Sigg li@t@ @ending from @igg-iten@ch
Wed May 30 14:19:04 CEST 2018


Hi Martin

Thank you for your reply.

> On 30 May 2018, at 12:03, Martin Maechler <maechler using stat.math.ethz.ch> wrote:
> 
>>>>>> Christian Sigg 
>>>>>>    on Wed, 30 May 2018 11:08:38 +0200 writes:
> 
>> I am updating the ’nsprcomp’ package to follow the recommendations of Section 1.1.3.1 of the Writing R Extensions manual.
>> Before the update, the example code for the `nsprcomp` function looked like this:
> 
>>> library(MASS)
>>> set.seed(1)
>>> 
>>> # Regular PCA, with the tolerance set to return five PCs
>>> prcomp(Boston, tol = 0.36, scale. = TRUE)
>>> 
>>> # Sparse PCA with different cardinalities per component. The number of components
>>> # is derived from the length of vector k.
>>> nsprcomp(Boston, k = c(13, 7, 5, 5, 5), scale. = TRUE)  
>>> 
>>> (…)
> 
> First, a only a "stylistic" remark to you (and many others):
> If you only need a dataset from a package, you typically should not attach the
> package [to the search() path] via library()/require(), but typically use
> 
>   data(Boston, package="MASS")
> 
> which only loads MASS' namespace *and* is self-describing that
> indeed you only use MASS for getting that data set.

I agree with you. In my specific example, I later also use MASS::ginv(), but unfortunately that was not visible in the excerpt.

> ... but see below for your real question
> 
>> The unconditional use of the suggested package ‘MASS’ produces an error on systems where ‘MASS’ is not installed. 
> 
>> I personally think that this is fine in an interactive session. The error makes it obvious what the user has to do to run the example - install the missing package. But I understand that it would increase the complexity of automated checking of examples, where one would have to distinguish between this kind of error and an actual bug in the example code.
> 
>> In any case, the WRE manual recommends conditional use of suggested packages via `requireNamespace`. A straightforward way to follow the recommendation is to wrap the whole example in a conditional statement:
> 
>>> if (requireNamespace("MASS", quietly = TRUE)) {
>>> set.seed(1)
>>> 
>>> # Regular PCA, with the tolerance set to return five PCs
>>> prcomp(MASS::Boston, tol = 0.36, scale. = TRUE)
>>> 
>>> # Sparse PCA with different cardinalities per component. The number of components
>>> # is derived from the length of vector k.
>>> nsprcomp(MASS::Boston, k = c(13, 7, 5, 5, 5), scale. = TRUE)  
>>> 
>>> (…)
>>> }
> 
>> I don’t like this for two reasons:
> 
>> 1. The if statement and the indentation add clutter to the example code, making the help page harder to read.
> 
>> 2. The if statement breaks the output of `example(“nsprcomp”, “nsprcomp”)`. Now only the statement before the closing curly brace has its output printed to the console. I would have to add explicit print statements that further clutter up the example.
> 
>> Is there a coding pattern that satisfies the WRE recommendations, but avoids these two problems?
> 
> A very good question:
> 
> I have introduced the function   withAutoprint( . )  into R 3.4.0  
> to address your '2.'  -- not perfectly but at least
> transparently,
> so the if would going to be
> 
>  if (requireNamespace("MASS", quietly = TRUE)) withAutoprint({
> 
> 
>  })
> 
> {and you'd have to add  'Depends: R (>= 3.4.0)’}

Thank you for that!

> 
> To address '1.'  you could wrap  \dontshow{ * } around the two
> if()-related lines in your example code which makes the code
> *look* better to the help page readers. 

But how do I only hide the if statement and its closing curly brace? The following doesn’t work:

> \examples{
>   \dontshow{
>     if (TRUE) {
>   }
>   test(1)
>   \dontshow{
>     }
>   }
> }


The example section on the help page is empty, because the curly braces of the if statement and the \dontshow get mixed up. 

Ordering the statements this way:

> \examples{
>   \dontshow{
>     if (TRUE) 
>   }
>   {
>     test(1)
>   }
> }

is better, but the opening and closing curly brace of the if statement remain on the help page. 

Furthermore, I keep the examples in standalone files that I include in the documentation using roxygen2’s @example. Adding the \dontshow markup means I can’t source them anymore.

> 
> These two "techniques" together get you quite far, though I
> agree it's a bit of fiddling..
> 
> Last but not least - of course you know that, I'm just stating
> the obvious here:  The small 'datasets' that comes with R
> does not need any conditionals (nor does simple random-generated
> data that you could use).

Quoting from the WRE manual:

> Some people have assumed that a ‘recommended’ package in ‘Suggests’ can safely be used unconditionally, but this is not so. (R can be installed without recommended packages, and which packages are ‘recommended’ may change.) 


So according to the manual, even MASS needs a conditional.

I do use random data in my tests, but I think that the examples profit from using a real dataset.

Regards
Christian

> 
> Best,
> Martin
> 
> 
>> Regards
>> Christian
> 
>>>> Christian Sigg
>> https://sigg-iten.ch/research
> 
>> ______________________________________________
>> R-package-devel using r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-package-devel



More information about the R-package-devel mailing list