On 14/08/2016 5:23 AM, Luca Cerone wrote:
Hi David and Duncan,
thanks for your answers!

I think what is not clear to me is actually how "substitute" works.

Arguments passed to R functions become a special kind of object known as a "promise". Promises contain two things: the expression to evaluate, and the value of the expression. The value isn't set at first. It is set by evaluating the expression when you use the argument as a regular variable in an expression for the first time. After that every use of it returns the same value, but the expression is retained.

When you call substitute() on an argument "arg", it returns the expression. substitute() also works on other kinds of objects that aren't promises; it generally returns their value. When you use it on a complex expression, it returns a new expression with undefined variables left alone, recognized variables substituted.


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).

I think your interpretation is right.


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.

The expression in the promise "package" is the expression "pkgname" (without quotes).


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.

That's not the value of y, it's the expression in y (which will be the same once it is evaluated). Peter gave an example where they differ, here's another:

> f(1+2)
x + (1 + 2)

Duncan Murdoch


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" <dwinsem...@comcast.net> wrote:


On Aug 12, 2016, at 8:57 AM, Luca Cerone <luca.cer...@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@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]]

______________________________________________
R-help@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@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.

Reply via email to