Skip to content

Rcmdr package dependencies

11 messages · John Fox, Gabor Grothendieck, Seth Falcon +1 more

#
Dear r-devel members,

My Rcmdr package "depends" on several other packages (tcltk, grDevices,
utils, and car) and "suggests" a number of others (abind, aplpack,
colorspace, effects, foreign, grid, Hmisc, lattice, leaps, lmtest, MASS,
mgcv, multcomp, nlme, nnet, relimp, rgl, and RODBC). The reason for the
distinction is that I don't want all of these packages to load when the
Rcmdr loads; rather, the "suggested" packages are loaded as they're needed.
But all of the packages -- both those under "depends" and those under
"suggests" -- really are necessary for all of the features of the Rcmdr to
work. For example, if the "leaps" package is absent, then the "Subset model
selection" item in the "Models" menu is suppressed.

This arrangement works reasonably well, but it makes it awkward to install
the Rcmdr. If the user issues the command install.packages("Rcmdr"), then
the "suggested" packages aren't installed. On the other hand, if the user
issues the command install.packages("Rcmdr", dependencies=TRUE), which is
what I currently recommend, then "suggested" packages are installed
recursively, causing dozens of packages, most of them actually unnecessary,
to be installed. This issue has been growing more acute, and at this point
even with a fast Internet connection it takes quite a while for all of the
dependencies to download and install.

I wonder whether I've missed something. Is there a way for me to arrange the
Rcmdr package dependencies so that only the necessary packages (those
currently listed under both "depends" and "suggests" and the packages on
which they "depend") are installed along with the Rcmdr, but the currently
"suggested" packages aren't loaded when the Rcmdr loads?

Any help would be appreciated.

John 

------------------------------
John Fox, Professor
Department of Sociology
McMaster University
Hamilton, Ontario, Canada
web: socserv.mcmaster.ca/jfox
#
John Fox wrote:
Dear John,

no, this is not possible.

Consider your package A (or Rcmdr) suggests B that suggests C.
Then A::foo uses the function B::bar which only works if C::dep is 
present. B works essentially without C but it requires C just to make 
bar work. Then this means your A::foo won't work if C is not installed 
and you won't get it with the setup mentioned above.

In summary, I fear what you want might work well *now* (by chance), but 
it does not work in general.

Best wishes,
Uwe
#
Create a package called RcmdrInstall, say, with no content and have it
depend on Rcmdr.  RcmdrInstall would have all packages as dependencies
while Rcmdr would only have the essential packages as dependencies.

Install RcmdrInstall.  That would also force Rcmdr to be installed.

Now issue:

   library(Rcmdr)

as before and the non-essentials won't be loaded.

Thus the only difference between the current procedure and the new
procedure as far as the user is concerned is that they install
RcmdrInstall rather than Rcmdr.  They load and run Rcmdr in the same
way.
On Tue, Sep 22, 2009 at 9:15 AM, John Fox <jfox at mcmaster.ca> wrote:
#
Dear Uwe,
needed.
to
model
install
then
user
is
unnecessary,
point
the
currently
I agree that what I want to do isn't bullet-proof. I think, however, that in
most, if not all, cases, the Rcmdr dialogs will work even if packages
suggested by currently directly suggested packages were not installed. In
fact, this is what happens when a package is installed with the default
dependencies=FALSE. If it turns out that some such indirect dependency is
actually necessary, I could add that package to those directly suggested
(were such a mechanism possible). I'd save users a lot of downloads at the
price of occasionally having to specify a dependency explicitly.

Thanks,
 John
#
Dear Gabor,

I thought of this solution but rejected it, perhaps too hastily, because it
seemed awkward. I suppose, however, that since the Rcmdr package would be
unchanged, a user could choose to install it as at present with
dependencies=TRUE, or alternatively install the RcmdrInstall package and
avoid the recursive installation of suggested packages. Maybe the idea is a
good one after all.

Thank you,
 John
needed.
to
model
install
then
user
is
unnecessary,
point
the
currently
#
To make it foolproof at Rcmdr's load time (i.e. in the .onLoad
function) you could check whether RcmdrInstall was available (not
necessarily loaded, just available).  If not, then you could issue a
message asking the user to install it.  This would help the user avoid
the situation where they install Rcmdr without RcmdrInstall and
thereby not have the other packages available.
On Tue, Sep 22, 2009 at 2:54 PM, John Fox <jfox at mcmaster.ca> wrote:
#
Dear Gabor,

At present, the Rcmdr package checks whether its dependencies are present
and offers to install them if they are not. Also at present, it installs its
dependencies with dep=TRUE, but that could be changed. I suppose that I
could simply rely on this mechanism rather than have a separate RcmdrInstall
package or advise users to install the Rcmdr itself with dep=TRUE.

Best,
 John
it
be
is a
grDevices,
MASS,
the
the
Rcmdr
which
of
arrange
on
#
John Fox wrote:
Thanks for the explanation. Unfortunately the current infrastructure 
works with recursive calling with the same arguments. In this case we'd 
need some code that allows to have the first level different from the 
rest of the recursion.
Perhaps one way to go would be to install Rcmdr including its 
dependencies (only) and provide some simple function that installs its 
suggests and their dependencies afterwards if not available. Hmmm, on he 
other hand I do now want to suggest to have yet another mechanism such 
as the biocLite function that I still dislike.

Just some thoughts, best wishes,
Uwe
#
* On 2009-09-22 at 20:16 +0200 Uwe Ligges wrote:
In general, one would expect a given package to function when its
suggested packages are not available.  As such, it seems quite
reasonable to install a package, its Depends, Imports, and Suggests,
but not install Suggests recursively.

I think you could achieve such an installation using two calls to
install.packages:

install.packages("Rcmdr")
Rcmdr.Suggests <- strsplit(packageDescription("Rcmdr")$Suggests, ",\\s?")[[1]]
## need extra cleanup since packageDescription("blah")$Suggests
## Returns package names with versions as strings
wantPkgs <- sub("^([^ ]+).*", "\\1", Rcmdr.Suggests)
havePkgs <- installed.packages()[, "Package"]
wantPkgs <- wantPkgs[!(wantPkgs %in% havePkgs)]
install.packages(wantPkgs)

+ seth
#
Dear Seth,
The Rcmdr maintains a list of its dependencies, so it already does something
similar to this, but I like your version better because it queries the
Description file directly. I can't really expect a user to issue a command
like this, so I suppose that the best solution is, as at present, to have
the Rcmdr package do the checking and installation at start-up but to
install with dep=FALSE.

Thanks,
 John
#
John Fox wrote:
Nice suggestion, indeed! I think there is some code in package "tools" 
that help to resolve these issues even more convenient:


wantPkgs <- package.dependencies(available.packages()["Rcmdr",], 
depLevel = "Suggests")[["Rcmdr"]][,1]

so you do not need to have Rcmdr already installed and can rely on the R 
internal code that can strip all that version information.

Best wishes,
Uwe