1

A follow-up to this question:

Why would an R package load random numbers?

I wonder if there's a way to generate a list of all packages that include some kind of random process when attached.

Sean Raleigh
  • 579
  • 4
  • 10
  • 1
    I guess I'm too inexperienced in StackOverflow to understand why the question was closed. The criteria listed ("to recommend or find a book, tool, software library, tutorial or other off-site resource") seem not to apply. The question has a clear objective and the excellent answer it attracted clearly solves the stated problem. – Sean Raleigh Apr 25 '18 at 02:55
  • Just curious if there's some kind of appeal here or if I'm way off base. In some ways, it doesn't matter if the question is closed because I got the answer I was looking for, but I don't know what other metrics or searchability are affected by the closure. And if "reword the question" is on the table, I'm happy to try if I can understand the criteria better. – Sean Raleigh Apr 28 '18 at 04:49

1 Answers1

2

I do not know of a way to be absolutely certain you've made an exhaustive list. However, we can check all of the installed packages on your system to see if it has a .onAttach() or .onLoad() function, and if so, whether it calls runif() or sample(), which I believe would be the most common cases of a package having some kind of random process when attached.1

check_packages <- function() {
    # get the names of all installed packages
    packs <- installed.packages()[ ,"Package"]
    # create an object to hold the names of packages that mess with the seed
    result <- character()
    # for each package
    for ( pack in packs ) {
        # see if it has an .onAttach or .onLoad function
        onattach <- try(getFromNamespace(".onAttach", pack), silent = TRUE)
        onload <- try(getFromNamespace(".onLoad", pack), silent = TRUE)
        # and if it does, check if it calls sample() or runif()
        if ( !inherits(onattach, "try-error") ) {
            if ( any(grepl("runif|sample", capture.output(onattach))) ) {
                # if so, add that package to the result object
                result <- c(result, pack)
                next()
            }
        }
        if ( !inherits(onload, "try-error") ) {
            if ( any(grepl("runif|sample", capture.output(onload))) ) {
                result <- c(result, pack)
                next()
            }
        }
    }
    # and return the names of all packages that do this
    return(result)
}

For me, this resulted in the following:

[1] "forecast" "ggplot2" 

As we see in my answer to the question you linked, ggplot2 does this to randomly select tips to display to the user. As it turns out, forecast does the same:

> forecast:::.onAttach
function (...) 
{
    if (!interactive() || stats::runif(1) > 0.2) 
        return()
    tips <- c("Use suppressPackageStartupMessages() to eliminate package startup messages.", 
        "Stackoverflow is a great place to get help on R issues:\n  http://stackoverflow.com/tags/forecasting+r.", 
        "Crossvalidated is a great place to get help on forecasting issues:\n  http://stats.stackexchange.com/tags/forecasting.", 
        "Need help getting started? Try the online textbook FPP:\n  http://OTexts.org/fpp/", 
        "Want to stay up-to-date? Read the Hyndsight blog:\n  https://robjhyndman.com/hyndsight/", 
        "Want to meet other forecasters? Join the International Institute of Forecasters:\n  http://forecasters.org/")
    tip <- sample(tips, 1)
    msg <- paste("This is forecast", packageVersion("forecast"), 
        "\n ", tip)
    packageStartupMessage(msg)
}
<bytecode: 0x10e92738>
<environment: namespace:forecast>


1 You could easily adapt the pattern in the grepl() call above to add arbitrary functions that call pseudo-random number generators.
duckmayr
  • 16,303
  • 3
  • 35
  • 53
  • So this seems like it's not a common problem. (Either that, or you don't have very many packages installed!) The warning in the `caret` package documentation doesn't seem all that urgent based on your results. – Sean Raleigh Apr 07 '18 at 23:01
  • @SeanRaleigh Exactly; out of 256 packages I have installed, only two met the criteria of the function above, so it does seem pretty rare. However, it can happen, so it's nice to be aware of it. – duckmayr Apr 07 '18 at 23:20