Dirk Eddelbuettel: #058: Reverse Dependencies Made Easy, Fast, Reliable
Welcome to post 58 in the R4 series.
R and the CRAN repositories maintain a very
high level of what we might call quality assurrance by requiring that
newly-added code does not break any existing dependencies. This is
frequently called a reverse-dependency check . For any given CRAN package one can quickly
determine it reverse dependencies. Calling
tools::package_dependencies(pkgName, reverse=TRUE) will for
a scalar or vector-valued argument return a named list with the reverse
dependencies. It is then a matter of looping over this list. There are
helper functions in base R as well as in contributed packages on and off
CRAN. I also wrote my own with
package prrd which,
while possibly a wee bit specialised and under-documented has served me
well to check on Rcpp and
related packages which can indeed have a large number of
reverse dependencies.
I recently looked into one of these contributed runner packages, and
while I will refrain from naming its implementation language let me just
mention that the term cargo cult may be a real thing
here. What go me interested in this was the fact that if one
has a simple-to-use runner then the fact that r2u makes it fast, easy,
reliable: pick all three (to borrow its slogan) to deal with actual
depencies if Ubuntu has indeed been selected as the host. We will
maintain the position that if you can in fact integrate with
the system-wide package management then any alternative per-repo package
management approach not doing so will likely be dominated by an approach
that does integrate with the system facilities. Which is what precisely
what r2u does, and
offers. And why it is used enough to by now have shipped eighty eight
million binary packages. So I tested it for the reverse-dependency check
task.
What I learned by looking into the (much more complicated) runner was
that it at the end of the day it hands the actual task of running the
reverse dependecies off to a helper function rev_check that
is part of the xfun package
by Yuhui. I quickly found that besides xfun we would also need its
suggested dependency tinytex which in turn
would error unless the tlmgr binary was present. So as the
sole requirement (on an Ubuntu system with r2u) turns out to be
where we do it all in one apt call (as root
in the container). (Given r2u we could also call
install.packages(c("xfun","tinytext")) followed by
apt install texlive-base but it is simpler for this setup
step to be just one call).
With that we are basically done. I did this (twice) using a
rocker/r2u container with r2u preinstalled, mounting
a local work and scrap directory for the container. In it we expand the
package to be tested (i.e. tar xaf pkgName_*tar.gz for a
given source package pkgName from CRAN) and then just call with the
package name and expanded direcrtory. I.e. I used this call to test my
package AsioHeaders (which has just three reverse
dependencies) to both name it and to point to the expanded source
directory created for this purposed:
> system.time( res <- xfun::rev_check("AsioHeaders", src="AsioHeaders") )
## ... earlier output omitted for brevity here ...
user system elapsed
35.732 3.333 149.683
> res
httpgd ipaddress websocket
0 0 0
> res. As I checked the current CRAN version, the check was as
expected free of concerns or issues.
To support this, r2u
did indeed go off and install about sixty seven binary packages (and the
total includes all binary dependencies fully resolved) delivering on the
just works promise by the r2u documentation.
As another check, I did the same for RcppAnnoy which has
seven reverse dependencies and needed about two hundred CRAN packages to be installed. The
full test took just over four minutes with the timing function reporting
some nice gains from parallelisation as total user compute time was on
the order of just under eight minutes. Again, test results were clean
and free of worries as expected:
> system.time( res <- xfun::rev_check("RcppAnnoy", src="RcppAnnoy") )
## ... earlier output omitted for brevity here ...
user system elapsed
471.765 378.220 266.855
> res
bbknnR bigANNOY blocking scDHA Seurat uwot VectrixDB
0 0 0 0 0 0 0
> This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub.

Odyssey displaying "The Great Wave Off Kanagawa"
Today I stumbled over some behavior that I found quite surprising:
While many Western democracies seem to be in a state of decay and are no longer the safe, civilized and prosperous countries they once were, there are still some European countries that are governed well. One of those that stand out is Estonia.
Estonia is probably most well known for multiple software companies that originated from there, such as
Estonians also seem to value the school system highly. The government has been actively
This is not just my personal experience. According to the
The next step is to buy a local prepaid SIM card at e.g., an R-Kiosk or a convenience store as signing up for other matters later on will require an Estonian phone number. Once you have an apartment and e.g., signed a rental agreement, you can register in the population registry online.
After that, you have proof you are a local resident with an address and telephone number in Estonia. With local resident status, you can go to the police station to get a local ID card. Don t bother scheduling an appointment, just go to the
The recurring joke is that because of some health issues, in summer I
dress like a Victorian Vampire.
But how would an actual Late Victorian Vampire dress? Picture her, she
would look like some kind of eccentric gentlewoman, as vampires usually
do, probably with a style that is a bit conservative, rather than
following the latest fashions.
Now, she wouldn t probably wear men s shirts. But what if she was a
lesbian
At the front, I wanted the ruffle to be inserted in the yoke, but I was
also whipstitching the gathers to it to make them neater, so I started
bu attaching the yoke lining to the gathered front, then I whipstitched
the ruffle to the front, catching each gather, and finally I
whipstitched the other yoke on the ruffle and the rest of the gathered
front.
And then after sewing the collar, I realized that this way the slit
would have remained open in the front (or the collar too narrow), so I
had to unpick the front part of the yoke, and sew it again, this time
leaving an excess of fabric as wide as half the placket width from the
pattern, to be sewn directly in the collar band.
From then, things progressed smoothly, with some interruptions, until I
got to the first sleeve, which I failed to insert twice, as one does.
On the third attempt, with a different method, I succeeded, I tried the
shirt on, and it already felt extra.
But it could be even more extra. With some ruffles also at the collar.
The shirt had been made with a simple collar band, and I could have just
added the ruffle to it, but I also wanted to be able to wear it with
other detachable collars, so I decided to make another collar band with
ruffles, to wear on top.
And that was mostly it, except for the reinforcement patches at the
side seams and cuffs: I love having them, because they make the seam
end neater and stronger, but they are a bit of a hassle to make, so they
got postponed a few days.
But finally, the shirt was done.
And I tried it on, and it was good.
But now I really need a pair of cycling breeches, don t I?

The Debian LTS Team, funded by [Freexian s Debian LTS offering]
(
Following up on my previous
Rather than constructing the Grafana dashboard from scratch, I used Claude 4.6
Sonnet via Antigravity to generate the layout configuration. The generated
dashboard for the local testbed functions effectively:
The complete, ready-to-import Grafana dashboard configuration is included
directly in the debvulns