George Trojan - NOAA Federal
2017-Feb-12 22:11 UTC
[R] Help with saving user defined functions
I can't figure out how to save functions to RDS file. Here is an example what I am trying to achieve:> t <- rnorm(100) > cdf <- ecdf(t) > cdf(0)[1] 0.59> saveRDS(cdf, "/tmp/foo") >Save workspace image? [y/n/c]: n [gtrojan at asok petproject]$ R> cdf <- readRDS("/tmp/foo") > cdfEmpirical CDF Call: ecdf(t) x[1:100] = -2.8881, -2.2054, -2.0026, ..., 2.0367, 2.0414 This works. However when instead of saving cdf() I try to save function> trans <- function(x) qnorm(cdf(x) * 0.99)after restoring object from file I get an error:> trans <- readRDS("/tmp/foo") > trans(0)Error in qnorm(cdf(x) * 0.99) : could not find function "cdf" I tried to define and call cdf within the definition of trans, without success:> tmp <- rnorm(100) > trans <- function(x) { cdf <- ecdf(tmp); cdf(0); qnorm(cdf(x)) * 0.99 } > saveRDS(trans, "/tmp/foo")Save workspace image? [y/n/c]: n> trans <- readRDS("/tmp/foo") > transfunction(x) { cdf <- ecdf(tmp); cdf(0); qnorm(cdf(x)) * 0.99 }> trans(0)Error in sort(x) : object 'tmp' not found So, here the call cdf(0) did not force evaluation of my random sample. What am I missing? George [[alternative HTML version deleted]]
It worked fine for me:> t <- rnorm(100) > cdf <- ecdf(t) > > trans <- function(x) qnorm(cdf(x) * 0.99) > saveRDS(trans, "/tmp/foo") > trans(1.2)[1] 1.042457> trans1 <- readRDS("/tmp/foo") > trans1(0)[1] 0.1117773 Of course, if I remove cdf() from the global environment, it will fail:> rm(cdf) > trans1(0)Error in qnorm(cdf(x) * 0.99) : could not find function "cdf" So it looks like you're clearing you global workspace in between saving and loading? You may need to read up on function closures/lexical scoping : A user-defined function in R includes not only code but also a pointer to the environment in which it was defined, in your case, the global environment from which you apparently removed cdf(). Note that functions are not evauated until called, so free variables in the functions that do not or will not exist in the function's lexical scope when called will not trigger any errors until the function *is* called. Same comments for your second version -- if tmp is removed the function will fail. 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 Sun, Feb 12, 2017 at 2:11 PM, George Trojan - NOAA Federal <george.trojan at noaa.gov> wrote:> I can't figure out how to save functions to RDS file. Here is an example > what I am trying to achieve: > >> t <- rnorm(100) >> cdf <- ecdf(t) >> cdf(0) > [1] 0.59 >> saveRDS(cdf, "/tmp/foo") >> > Save workspace image? [y/n/c]: n > [gtrojan at asok petproject]$ R >> cdf <- readRDS("/tmp/foo") >> cdf > Empirical CDF > Call: ecdf(t) > x[1:100] = -2.8881, -2.2054, -2.0026, ..., 2.0367, 2.0414 > > This works. However when instead of saving cdf() I try to save function > >> trans <- function(x) qnorm(cdf(x) * 0.99) > > after restoring object from file I get an error: > >> trans <- readRDS("/tmp/foo") >> trans(0) > Error in qnorm(cdf(x) * 0.99) : could not find function "cdf" > > I tried to define and call cdf within the definition of trans, without > success: > >> tmp <- rnorm(100) >> trans <- function(x) { cdf <- ecdf(tmp); cdf(0); qnorm(cdf(x)) * 0.99 } >> saveRDS(trans, "/tmp/foo") > Save workspace image? [y/n/c]: n > >> trans <- readRDS("/tmp/foo") >> trans > function(x) { cdf <- ecdf(tmp); cdf(0); qnorm(cdf(x)) * 0.99 } >> trans(0) > Error in sort(x) : object 'tmp' not found > > So, here the call cdf(0) did not force evaluation of my random sample. What > am I missing? > > George > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
So doesn't the fact that a function contains a reference to an environment suggest that this whole exercise is a really bad idea? -- Sent from my phone. Please excuse my brevity. On February 12, 2017 4:05:31 PM PST, Bert Gunter <bgunter.4567 at gmail.com> wrote:>It worked fine for me: > >> t <- rnorm(100) >> cdf <- ecdf(t) >> >> trans <- function(x) qnorm(cdf(x) * 0.99) >> saveRDS(trans, "/tmp/foo") >> trans(1.2) >[1] 1.042457 >> trans1 <- readRDS("/tmp/foo") >> trans1(0) >[1] 0.1117773 > > >Of course, if I remove cdf() from the global environment, it will fail: > >> rm(cdf) >> trans1(0) >Error in qnorm(cdf(x) * 0.99) : could not find function "cdf" > >So it looks like you're clearing you global workspace in between >saving and loading? > >You may need to read up on function closures/lexical scoping : A >user-defined function in R includes not only code but also a pointer >to the environment in which it was defined, in your case, the global >environment from which you apparently removed cdf(). Note that >functions are not evauated until called, so free variables in the >functions that do not or will not exist in the function's lexical >scope when called will not trigger any errors until the function *is* >called. > >Same comments for your second version -- if tmp is removed the >function will fail. > > > >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 Sun, Feb 12, 2017 at 2:11 PM, George Trojan - NOAA Federal ><george.trojan at noaa.gov> wrote: >> I can't figure out how to save functions to RDS file. Here is an >example >> what I am trying to achieve: >> >>> t <- rnorm(100) >>> cdf <- ecdf(t) >>> cdf(0) >> [1] 0.59 >>> saveRDS(cdf, "/tmp/foo") >>> >> Save workspace image? [y/n/c]: n >> [gtrojan at asok petproject]$ R >>> cdf <- readRDS("/tmp/foo") >>> cdf >> Empirical CDF >> Call: ecdf(t) >> x[1:100] = -2.8881, -2.2054, -2.0026, ..., 2.0367, 2.0414 >> >> This works. However when instead of saving cdf() I try to save >function >> >>> trans <- function(x) qnorm(cdf(x) * 0.99) >> >> after restoring object from file I get an error: >> >>> trans <- readRDS("/tmp/foo") >>> trans(0) >> Error in qnorm(cdf(x) * 0.99) : could not find function "cdf" >> >> I tried to define and call cdf within the definition of trans, >without >> success: >> >>> tmp <- rnorm(100) >>> trans <- function(x) { cdf <- ecdf(tmp); cdf(0); qnorm(cdf(x)) * >0.99 } >>> saveRDS(trans, "/tmp/foo") >> Save workspace image? [y/n/c]: n >> >>> trans <- readRDS("/tmp/foo") >>> trans >> function(x) { cdf <- ecdf(tmp); cdf(0); qnorm(cdf(x)) * 0.99 } >>> trans(0) >> Error in sort(x) : object 'tmp' not found >> >> So, here the call cdf(0) did not force evaluation of my random >sample. What >> am I missing? >> >> George >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. > >______________________________________________ >R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >https://stat.ethz.ch/mailman/listinfo/r-help >PLEASE do read the posting guide >http://www.R-project.org/posting-guide.html >and provide commented, minimal, self-contained, reproducible code.
George Trojan - NOAA Federal
2017-Feb-13 01:31 UTC
[R] Help with saving user defined functions
I want to split my computation into parts. The first script processes the data, the second does the graphics. I want to save results of time-consuming calculations. My example tried to simulate this by terminate the session without saving it, so the environment was lost on purpose. What confuses me that ecdf can be saved and restored, but not my own derived function. Of course I can save parameters and redefine the function in the second script. Reading Chapter 8 of Advanced R, hopefully the book will clear my mind. On Mon, Feb 13, 2017 at 12:05 AM, Bert Gunter <bgunter.4567 at gmail.com> wrote:> It worked fine for me: > > > t <- rnorm(100) > > cdf <- ecdf(t) > > > > trans <- function(x) qnorm(cdf(x) * 0.99) > > saveRDS(trans, "/tmp/foo") > > trans(1.2) > [1] 1.042457 > > trans1 <- readRDS("/tmp/foo") > > trans1(0) > [1] 0.1117773 > > > Of course, if I remove cdf() from the global environment, it will fail: > > > rm(cdf) > > trans1(0) > Error in qnorm(cdf(x) * 0.99) : could not find function "cdf" > > So it looks like you're clearing you global workspace in between > saving and loading? > > You may need to read up on function closures/lexical scoping : A > user-defined function in R includes not only code but also a pointer > to the environment in which it was defined, in your case, the global > environment from which you apparently removed cdf(). Note that > functions are not evauated until called, so free variables in the > functions that do not or will not exist in the function's lexical > scope when called will not trigger any errors until the function *is* > called. > > Same comments for your second version -- if tmp is removed the > function will fail. > > > > 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 Sun, Feb 12, 2017 at 2:11 PM, George Trojan - NOAA Federal > <george.trojan at noaa.gov> wrote: > > I can't figure out how to save functions to RDS file. Here is an example > > what I am trying to achieve: > > > >> t <- rnorm(100) > >> cdf <- ecdf(t) > >> cdf(0) > > [1] 0.59 > >> saveRDS(cdf, "/tmp/foo") > >> > > Save workspace image? [y/n/c]: n > > [gtrojan at asok petproject]$ R > >> cdf <- readRDS("/tmp/foo") > >> cdf > > Empirical CDF > > Call: ecdf(t) > > x[1:100] = -2.8881, -2.2054, -2.0026, ..., 2.0367, 2.0414 > > > > This works. However when instead of saving cdf() I try to save function > > > >> trans <- function(x) qnorm(cdf(x) * 0.99) > > > > after restoring object from file I get an error: > > > >> trans <- readRDS("/tmp/foo") > >> trans(0) > > Error in qnorm(cdf(x) * 0.99) : could not find function "cdf" > > > > I tried to define and call cdf within the definition of trans, without > > success: > > > >> tmp <- rnorm(100) > >> trans <- function(x) { cdf <- ecdf(tmp); cdf(0); qnorm(cdf(x)) * 0.99 } > >> saveRDS(trans, "/tmp/foo") > > Save workspace image? [y/n/c]: n > > > >> trans <- readRDS("/tmp/foo") > >> trans > > function(x) { cdf <- ecdf(tmp); cdf(0); qnorm(cdf(x)) * 0.99 } > >> trans(0) > > Error in sort(x) : object 'tmp' not found > > > > So, here the call cdf(0) did not force evaluation of my random sample. > What > > am I missing? > > > > George > > > > [[alternative HTML version deleted]] > > > > ______________________________________________ > > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > > https://stat.ethz.ch/mailman/listinfo/r-help > > PLEASE do read the posting guide http://www.R-project.org/ > posting-guide.html > > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]