Luca Cerone
2016-Aug-12 15:57 UTC
[R] Help with non standard evaluation and require function
Hi everybody, I am having a hard time in understanding how to deal with non standard evaluation and the require function. I asked about it on Stackoverflow at http://stackoverflow.com/questions/38922012/r-function-to-install-missing-packages, below you can find my question. Thanks a lot for the help! Cheers, Luca For one of my scripts I want to write an R function that checks if a package is already installed: if so it should use library() to import it in the namespace, otherwise it should install it and import it. I assumed that pkgname is a string and tried to write something like: ensure_library <- function(pkgname) { if (!require(pkgname)) { install.packages(pkgname, dependencies = TRUE) } require(pkgname) } As simple as is this function does not work. If I try to run it like ensure_library("dplyr") it installs the package dplyr but then it fails because it trys to import pkgname rather than dplyr in the namespace. ensure_library("dplyr") Loading required package: pkgname Installing package into ?/home/luca/R-dev? (as ?lib? is unspecified) trying URL 'https://cran.rstudio.com/src/contrib/dplyr_0.5.0.tar.gz' Content type 'application/x-gzip' length 708476 bytes (691 KB) =================================================downloaded 691 KB * installing *source* package ?dplyr? ... ** package ?dplyr? successfully unpacked and MD5 sums checked ** libs .... a lot of compiling here.... installing to /home/luca/R-dev/dplyr/libs ** R ** data *** moving datasets to lazyload DB ** inst ** preparing package for lazy loading ** help *** installing help indices ** building package indices ** installing vignettes ** testing if installed package can be loaded * DONE (dplyr) The downloaded source packages are in ?/tmp/Rtmpfd2Lep/downloaded_packages? Loading required package: pkgname Warning messages: 1: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, : there is no package called ?pkgname? 2: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, : there is no package called ?pkgname? Also, if I now re-run it it will install dplyr once again. I realize this is probably due to R non-standard-evaluation and I have tried several combination of eval/substitute/quote in order to make it work with require but I couldn't succeed. Can somebody help me understanding what is going on and if there is some easy-fix? If a function already implementing this exists I would like to know, but what I am really interested is understanding why my code does not work as intended.
Duncan Murdoch
2016-Aug-12 16:18 UTC
[R] Help with non standard evaluation and require function
On 12/08/2016 11:57 AM, Luca Cerone wrote:> Hi everybody, > I am having a hard time in understanding how to deal with non standard > evaluation and the require function. > > I asked about it on Stackoverflow at > http://stackoverflow.com/questions/38922012/r-function-to-install-missing-packages, > below you can find my question. > > Thanks a lot for the help! > Cheers, > Luca > > For one of my scripts I want to write an R function that checks if a > package is already installed: if so it should use library() to import > it in the namespace, otherwise it should install it and import it. > > I assumed that pkgname is a string and tried to write something like: > > ensure_library <- function(pkgname) { > if (!require(pkgname)) {Should be if (!require(pkgname, character.only = TRUE)) {> install.packages(pkgname, dependencies = TRUE) > } > require(pkgname)Similarly here. You won't need this for the install.packages call. You should have been able to figure this out from the ?require help page. It is mentioned twice, and is used in one of the examples. Duncan Murdoch
David Winsemius
2016-Aug-12 18:14 UTC
[R] Help with non standard evaluation and require function
> On Aug 12, 2016, at 8:57 AM, Luca Cerone <luca.cerone at gmail.com> wrote: > > Hi everybody, > I am having a hard time in understanding how to deal with non standard > evaluation and the require function. > > I asked about it on Stackoverflow at > http://stackoverflow.com/questions/38922012/r-function-to-install-missing-packages, > below you can find my question.It was already explained and teh code of `require provided: `substitute` does not lookup values in the symbol table so the symbol: `pkgname` is converted by `as.character` to "pkgname", .... unless 'character.only' is TRUE. What part of that is not understood? -- David.> > Thanks a lot for the help! > Cheers, > Luca > > For one of my scripts I want to write an R function that checks if a > package is already installed: if so it should use library() to import > it in the namespace, otherwise it should install it and import it. > > I assumed that pkgname is a string and tried to write something like: > > ensure_library <- function(pkgname) { > if (!require(pkgname)) { > install.packages(pkgname, dependencies = TRUE) > } > require(pkgname) > } > > As simple as is this function does not work. If I try to run it like > ensure_library("dplyr") it installs the package dplyr but then it > fails because it trys to import pkgname rather than dplyr in the > namespace. > > ensure_library("dplyr") > Loading required package: pkgname > Installing package into ?/home/luca/R-dev? > (as ?lib? is unspecified) > trying URL 'https://cran.rstudio.com/src/contrib/dplyr_0.5.0.tar.gz' > Content type 'application/x-gzip' length 708476 bytes (691 KB) > =================================================> downloaded 691 KB > > * installing *source* package ?dplyr? ... > ** package ?dplyr? successfully unpacked and MD5 sums checked > ** libs > > .... a lot of compiling here.... > > installing to /home/luca/R-dev/dplyr/libs > ** R > ** data > *** moving datasets to lazyload DB > ** inst > ** preparing package for lazy loading > ** help > *** installing help indices > ** building package indices > ** installing vignettes > ** testing if installed package can be loaded > * DONE (dplyr) > > The downloaded source packages are in > ?/tmp/Rtmpfd2Lep/downloaded_packages? > Loading required package: pkgname > Warning messages: > 1: In library(package, lib.loc = lib.loc, character.only = TRUE, > logical.return = TRUE, : > there is no package called ?pkgname? > 2: In library(package, lib.loc = lib.loc, character.only = TRUE, > logical.return = TRUE, : > there is no package called ?pkgname? > > Also, if I now re-run it it will install dplyr once again. > > I realize this is probably due to R non-standard-evaluation and I have > tried several combination of eval/substitute/quote in order to make it > work with require but I couldn't succeed. > > Can somebody help me understanding what is going on and if there is > some easy-fix? > > If a function already implementing this exists I would like to know, > but what I am really interested is understanding why my code does not > work as intended. > > ______________________________________________ > 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.David Winsemius Alameda, CA, USA
Luca Cerone
2016-Aug-14 09:23 UTC
[R] Help with non standard evaluation and require function
Hi David and Duncan, thanks for your answers! I think what is not clear to me is actually how "substitute" works. If I run require (dplyr) or require("dplyr") in the R console everything works as I expect even without the character.only=T (actually because of this I always interpreted that character.only=F means you can either use nse or strings while with character.only=T you can only use strings). What I don't understand is why in the require function as.character (substitute(package)) returns "pkgname" (the name of the variable I use in my function) rather than substituting the value of pkgname i.e. dplyr in my example. I have no access to my laptop so I can't double check but I think in one of Wickham's book there was an example like f <- function (y) { substitute (x + y) } f(4) [1] x + 4 i.e. where substitute inside a function was substituting the value of y and returned the expression replacing y with 4, which is what I would expect to happen. It is probaby a very trivial problem but I find hard to figure out ho substitute works. Thanks a lot again for the help! Cheers, Luca On Aug 12, 2016 20:14, "David Winsemius" <dwinsemius at comcast.net> wrote:> > > On Aug 12, 2016, at 8:57 AM, Luca Cerone <luca.cerone at gmail.com> wrote: > > > > Hi everybody, > > I am having a hard time in understanding how to deal with non standard > > evaluation and the require function. > > > > I asked about it on Stackoverflow at > > http://stackoverflow.com/questions/38922012/r-function- > to-install-missing-packages, > > below you can find my question. > > It was already explained and teh code of `require provided: `substitute` > does not lookup values in the symbol table so the symbol: `pkgname` is > converted by `as.character` to "pkgname", .... unless 'character.only' is > TRUE. > > What part of that is not understood? > > -- > David. > > > > Thanks a lot for the help! > > Cheers, > > Luca > > > > For one of my scripts I want to write an R function that checks if a > > package is already installed: if so it should use library() to import > > it in the namespace, otherwise it should install it and import it. > > > > I assumed that pkgname is a string and tried to write something like: > > > > ensure_library <- function(pkgname) { > > if (!require(pkgname)) { > > install.packages(pkgname, dependencies = TRUE) > > } > > require(pkgname) > > } > > > > As simple as is this function does not work. If I try to run it like > > ensure_library("dplyr") it installs the package dplyr but then it > > fails because it trys to import pkgname rather than dplyr in the > > namespace. > > > > ensure_library("dplyr") > > Loading required package: pkgname > > Installing package into ?/home/luca/R-dev? > > (as ?lib? is unspecified) > > trying URL 'https://cran.rstudio.com/src/contrib/dplyr_0.5.0.tar.gz' > > Content type 'application/x-gzip' length 708476 bytes (691 KB) > > =================================================> > downloaded 691 KB > > > > * installing *source* package ?dplyr? ... > > ** package ?dplyr? successfully unpacked and MD5 sums checked > > ** libs > > > > .... a lot of compiling here.... > > > > installing to /home/luca/R-dev/dplyr/libs > > ** R > > ** data > > *** moving datasets to lazyload DB > > ** inst > > ** preparing package for lazy loading > > ** help > > *** installing help indices > > ** building package indices > > ** installing vignettes > > ** testing if installed package can be loaded > > * DONE (dplyr) > > > > The downloaded source packages are in > > ?/tmp/Rtmpfd2Lep/downloaded_packages? > > Loading required package: pkgname > > Warning messages: > > 1: In library(package, lib.loc = lib.loc, character.only = TRUE, > > logical.return = TRUE, : > > there is no package called ?pkgname? > > 2: In library(package, lib.loc = lib.loc, character.only = TRUE, > > logical.return = TRUE, : > > there is no package called ?pkgname? > > > > Also, if I now re-run it it will install dplyr once again. > > > > I realize this is probably due to R non-standard-evaluation and I have > > tried several combination of eval/substitute/quote in order to make it > > work with require but I couldn't succeed. > > > > Can somebody help me understanding what is going on and if there is > > some easy-fix? > > > > If a function already implementing this exists I would like to know, > > but what I am really interested is understanding why my code does not > > work as intended. > > > > ______________________________________________ > > 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. > > David Winsemius > Alameda, CA, USA > >[[alternative HTML version deleted]]