Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are these strings or variables?

Tags:

r

ggplot2

Coming from a C / Python / Java background, I have trouble understanding some R syntax, where literals look like variables, but seem to behave like strings. For example:

library(ggplot2) library("ggplot2") 

The two lines behave equivalently. However, I would expect the first line to mean "load the library whose name is stored in the ggplot2 variable" and give an error like object 'ggplot2' not found.

Speaking of ggplot2:

ggplot(data, aes(factor(arrivalRate), responseTime, fill=factor(mode))) +   geom_violin(trim=FALSE, position=dodge) 

The variables arrivalRate, responseTime and mode do not exist, but somehow R knows to look them up inside the data data frame. I assume that aes actually receives strings, that are then processed using something like eval.

How does R parse code that it ends up interpreting some literals as strings?

like image 311
user1202136 Avatar asked Nov 24 '17 22:11

user1202136


People also ask

How do you check if a variable is string or not?

Use the typeof operator to check if a variable is a string, e.g. if (typeof variable === 'string') . If the typeof operator returns "string" , then the variable is a string. In all other cases the variable isn't a string.

What are strings and variables?

A Variable is a store of information, and a String is a type of information you would store in a Variable. A String is usually words, enclosed with "" Eg String x ="Welcome to SoloLearn" X is the Variable, and we declared it as a String, use the single = to assign the text to it.

Are strings variables or objects?

Yes, @Dgrin91, a String is an object.

Is a string literal or variable?

A string literal is where you specify the contents of a string in a program. Here 'A string' is a string literal. The variable a is a string variable, or, better put in Python, a variable that points to a string.


1 Answers

promises

When an argument is passed to a function it is not passed as a value but is passed as a promise which consists of

  • the expression or code that the caller uses as the actual argument
  • the environment in which that expression is to be evaluated, viz. the caller's environment.
  • the value that the expression represents when the expression is evaluated in the promise's environment -- this slot is not filled in until the promise is actually evaluated. It will never be filled in if the function never accesses it.

The pryr package can show the info in a promise:

library(pryr)  g <- function(x) promise_info(x) g(ggplot2) 

giving:

$code ggplot2  <-- the promise x represents the expression ggplot2  $env <environment: R_GlobalEnv>  <-- if evaluated it will be done in this environment  $evaled [1] FALSE  <-- it has not been evaluated  $value NULL  <-- not filled in because promise has not been evaluated 

The only one of the above slots in the pryr output that can be accessed at the R level without writing a C function to do it (or using a package such as pryr that accesses such C code) is the code slot. That can be done using the R function substitute(x) (or other means). In terms of the pryr output substitute applied to a promise returns the code slot without evaluating the promise. That is, the value slot is not modified. Had we accessed x in an ordinary way, i.e. not via substitute, then the code would have been evaluated in the promise's environment, stored in the value slot and then passed to the expression in the function that accesses it.

Thus either of the following result in a character string representing what was passed as an expression, i.e. the character representation of the code slot, as opposed to its value.

f <- function(x) as.character(substitute(x)) f("ggplot2") ## [1] "ggplot2" f(ggplot2) ## [1] "ggplot2" 

library

In fact, library uses this idiom, i.e. as.character(substitute(x)), to handle its first argument.

aes

The aes function uses match.call to get the entire call as an expression and so in a sense is an alternative to substitute. For example:

h <- function(x) match.call() h(pi + 3) ## h(x = pi + 3) 

Note

One cannot tell without looking at the documentation or code of a function how it will treat its arguments.

like image 67
G. Grothendieck Avatar answered Sep 29 '22 11:09

G. Grothendieck