Hi Bert, Thanks for your response. What you suggest is more or less the fix I suggested in my email (my second version of .rcolors). I writing more because I was wondering if there was a better way to work with RNG that would avoid doing that. It doesn?t feel very friendly for my package to be making changes to the user?s global environment, even though I am setting them back (and if it weren?t for the fact that setting the new R 3.6 argument `sample.kind=?Rounding?` creates a warning, I wouldn?t have even realized I was affecting the user?s settings, so it seems potentially hazardous that packages could be changing users settings without them being aware of it). So I was wondering if there was a way to more fully isolate the command. Thanks, Elizabeth> On Apr 16, 2019, at 9:36 AM, Bert Gunter <bgunter.4567 at gmail.com> wrote: > > I think I'm missing something. Why does something like this not do what you want: > > > RNGkind() > [1] "Mersenne-Twister" "Inversion" > > f <- function(){ > + cur <- RNGkind(NULL)[1] > + RNGkind("Super-Duper") > + print(RNGkind()) > + RNGkind(cur) > + } > > f() > [1] "Super-Duper" "Inversion" > > RNGkind() > [1] "Mersenne-Twister" "Inversion" > > Cheers, > Bert > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along and sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > > On Tue, Apr 16, 2019 at 9:13 AM Elizabeth Purdom <epurdom at stat.berkeley.edu <mailto:epurdom at stat.berkeley.edu>> wrote: > Hello, > > I have a package, and inside of it I have a small function that selects a random palette of colors for graphing purposes. It?s a large number of colors, which is why I don?t manually select them, but I did want them to stay constant so I set the seed before doing so. So I had a little function in my package that does this: > > .rcolors<-function(){ > set.seed(23589) > x<-sample(colors()[-c(152:361)]) > return(x) > } > massivePalette<-unique(c(bigPalette,.rcolors())) > > Now that the sample function has been changed in R 3.6, I would need to use `sample.kind=?Rounding?` to get the same set of colors as I had previously. However, I don?t want to do that in my package, because that appears to change the global environment sampling: > > > RNGkind() > [1] "Mersenne-Twister" "Inversion" "Rejection" > > RNGkind(sample.kind="Rejection") > > x<-clusterExperiment:::.rcolors() #now I have changed the function so that sample.kind=?Rounding? ? I?ve suppressed the warnings > > RNGkind() > [1] "Mersenne-Twister" "Inversion" "Rounding? > > So I could do something like this: > > .rcolors<-function(){ > currentRNG<-RNGkind() > suppressWarnings(RNGkind(sample.kind="Rounding")) > set.seed(23589) > x<-sample(colors()[-c(152:361)]) > #set it back to default > suppressWarnings(RNGkind(sample.kind=currentRNG[3])) > return(x) > } > > But is there a way to change the random sampling in the function environment and not change it in the global environment? (For this function, I can just break down and accept that I will have different colors from this point on, but I?d like to know more generally; especially since it means that my `fixed` colors are not really fixed since they depend on the user?s setting of random sampling techniques, which I hadn?t considered before). > > All of the best, > Elizabeth Purdom > > ______________________________________________ > R-help at r-project.org <mailto:R-help at r-project.org> mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help <https://stat.ethz.ch/mailman/listinfo/r-help> > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html <http://www.r-project.org/posting-guide.html> > and provide commented, minimal, self-contained, reproducible code.[[alternative HTML version deleted]]
>>>>> Elizabeth Purdom >>>>> on Tue, 16 Apr 2019 09:45:45 -0700 writes:> Hi Bert, Thanks for your response. What you suggest is > more or less the fix I suggested in my email (my second > version of .rcolors). I writing more because I was > wondering if there was a better way to work with RNG that > would avoid doing that. It doesn?t feel very friendly for > my package to be making changes to the user?s global > environment, even though I am setting them back (and if it > weren?t for the fact that setting the new R 3.6 argument > `sample.kind=?Rounding?` creates a warning, I wouldn?t > have even realized I was affecting the user?s settings, so > it seems potentially hazardous that packages could be > changing users settings without them being aware of > it). So I was wondering if there was a way to more fully > isolate the command. Thanks, Elizabeth Hi Elizabeth, there's actually something better -- I think -- that you can do: You store .Random.seed before doing an RNGkind() & set.seed() setting, do all that, and make sure that .Random.seed is restored when leaving your function. This works because the (typically quite long) .Random.seed stores the full state of the RNG, i.e., all RNGkind() settings *and* the result of set.seed() , calling r<foo>(n, ..) etc. If you additionally use on.exit() instead of manually reset things, you have the additional advantage, that things are also reset when your functions ends because the user interrupts its computations, or an error happens, etc. So, your function would more elegantly (and robustly!) look like .rcolors <- function(seed = 23589) { if(!exists(".Random.seed", envir = .GlobalEnv)) { message("calling runif(1)"); runif(1) } old.R.s <- .Random.seed ## will reset everything on exiting this function: on.exit(assign(".Random.seed", old.R.s, envir=.GlobalEnv)) ## set seed for sample() "back compatibly": suppressWarnings(RNGversion("3.5.0")) set.seed(seed) ## return random permutation of "my colors" sample(colors()[-c(152:361)]) } BTW, you can look at simulate() methods in standard R, e.g., stats:::simulate.lm to see the same method use [optionally, with slightly more sophistication] Best, Martin Martin M?chler ETH Zurich, Switzerland
Thanks Martin, this seems much better. All of the best, Elizabeth> On Apr 16, 2019, at 10:22 AM, Martin Maechler <maechler at stat.math.ethz.ch> wrote: > >>>>>> Elizabeth Purdom >>>>>> on Tue, 16 Apr 2019 09:45:45 -0700 writes: > >> Hi Bert, Thanks for your response. What you suggest is >> more or less the fix I suggested in my email (my second >> version of .rcolors). I writing more because I was >> wondering if there was a better way to work with RNG that >> would avoid doing that. It doesn?t feel very friendly for >> my package to be making changes to the user?s global >> environment, even though I am setting them back (and if it >> weren?t for the fact that setting the new R 3.6 argument >> `sample.kind=?Rounding?` creates a warning, I wouldn?t >> have even realized I was affecting the user?s settings, so >> it seems potentially hazardous that packages could be >> changing users settings without them being aware of >> it). So I was wondering if there was a way to more fully >> isolate the command. Thanks, Elizabeth > > Hi Elizabeth, > > there's actually something better -- I think -- that you can do: > > You store .Random.seed before doing an RNGkind() & set.seed() > setting, do all that, and make sure that .Random.seed is > restored when leaving your function. > > This works because the (typically quite long) .Random.seed > stores the full state of the RNG, i.e., all RNGkind() settings > *and* the result of set.seed() , calling r<foo>(n, ..) etc. > > If you additionally use on.exit() instead of manually reset > things, you have the additional advantage, that things are also > reset when your functions ends because the user interrupts its > computations, or an error happens, etc. > > So, your function would more elegantly (and robustly!) look like > > .rcolors <- function(seed = 23589) { > if(!exists(".Random.seed", envir = .GlobalEnv)) { > message("calling runif(1)"); runif(1) } > old.R.s <- .Random.seed > ## will reset everything on exiting this function: > on.exit(assign(".Random.seed", old.R.s, envir=.GlobalEnv)) > ## set seed for sample() "back compatibly": > suppressWarnings(RNGversion("3.5.0")) > set.seed(seed) > ## return random permutation of "my colors" > sample(colors()[-c(152:361)]) > } > > BTW, you can look at simulate() methods in standard R, e.g., > > stats:::simulate.lm > > to see the same method use [optionally, with slightly more sophistication] > > > Best, > Martin > > Martin M?chler > ETH Zurich, Switzerland