32 votes

S'agit-il de chaînes ou de variables?

Venant d'un C / Python / Java arrière-plan, j'ai de la difficulté à comprendre certains R de la syntaxe, où les littéraux de ressembler à des variables, mais semblent se comporter comme des cordes. Par exemple:

library(ggplot2)
library("ggplot2")

Les deux lignes se comporter de manière équivalente. Toutefois, je m'attends à ce que la première ligne est à dire, "charger la bibliothèque dont le nom est stocké dans la ggplot2 variable" et donner un message d'erreur tel que object 'ggplot2' not found.

En parlant de ggplot2:

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

Les variables arrivalRate, responseTime et mode n'existent pas, mais de toute façon R sait les regarder à l'intérieur de l' data bloc de données. Je suppose qu' aes reçoit effectivement les chaînes, qui sont ensuite traitées à l'aide de quelque chose comme eval.

Comment ne R analyser le code qu'il finit par l'interprétation de certains littéraux de chaînes?

28voto

G. Grothendieck Points 40825

promesses

Quand un argument est passé à une fonction, il n'est pas passée comme une valeur, mais il est passé comme une promesse qui se compose de

  • l'expression ou le code que l'appelant utilise comme argument réel
  • l'environnement dans lequel cette expression est évaluée, viz. l'appelant de l'environnement.
  • la valeur de l'expression représente quand l'expression est évaluée dans la promesse de l'environnement -- cette fente n'est pas rempli, jusqu'à ce que la promesse est réellement évalué. Il ne sera jamais remplie si la fonction ne jamais y accéder.

Le pryr package peut afficher les infos dans une promesse:

library(pryr)

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

donner:

$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

Le seul au-dessus des fentes dans la pryr de sortie qui peut être consulté au niveau R sans écrire une fonction C pour le faire (ou à l'aide d'un package comme pryr qui accède à un tel code C) est le code de la fente. Qui peut être fait à l'aide de la fonction R substitute(x) (ou par d'autres moyens). En termes de pryr de sortie substitute appliqué à une promesse renvoie le code de la fente sans évaluation de la promesse. C'est la valeur fente n'est pas modifié. Si on l'avait consulté x de manière ordinaire, c'est à dire pas par l'intermédiaire d' substitute, puis le code aurait été évalués dans la promesse de l'environnement, stocké dans la valeur de la fente et ensuite transmis à l'expression de la fonction qui y accède.

Donc soit le résultat suivant dans une chaîne de caractères représentant ce qui a été transmis comme une expression, c'est à dire la représentation des caractères du code du logement, par opposition à sa valeur.

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

bibliothèque

En fait, library utilise ce langage, c'est à dire as.character(substitute(x)), à manipuler son premier argument.

aes

L' aes fonction match.call pour obtenir l'ensemble de l'appel comme une expression et donc, en un sens, est une alternative à l' substitute. Par exemple:

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

Note

On ne peut pas dire sans regarder la documentation ou le code d'une fonction de comment il va traiter ses arguments.

20voto

jdobres Points 4500

Une intéressante caprice de la R langue est la façon dont il évalue les expressions. Dans la plupart des cas, R comporte de la façon dont vous vous attendez. Les Expressions entre guillemets sont traitées comme des chaînes, tout le reste est traité comme une variable, une fonction ou un autre jeton. Mais certaines fonctions permettent de "non-standard de l'évaluation", dans lequel un non cotées dont l'expression est évaluée, plus ou moins, comme si c'était une cité variable. L'exemple le plus commun de ce qui est R la façon de charger les bibliothèques (qui permet de sociétés non cotées ou cotées, les noms de bibliothèque) et de ses succincte de la formule de l'interface. D'autres paquets peuvent profiter de la NSE. Hadley Wickham rend l'utilisation intensive de l'informatique tout au long de sa très populaire tidyverse paquets. Mis à part économiser l'utilisateur quelques caractères de la dactylographie, de la NSE a un certain nombre de propriétés utiles pour la programmation dynamique.

Comme indiqué dans l'autre réponse, Wickham a un excellent tutoriel sur comment tout cela fonctionne. RPubs utilisateur lionel a aussi un excellent document de travail sur le sujet.

7voto

Claus Wilke Points 7757

Le concept est appelé "non-standard de l'évaluation", et il existe de nombreuses façons dans lesquelles il peut être utilisé dans différentes fonctions R. Voir ce chapitre de livre pour une introduction.

Cette fonctionnalité peut être source de confusion, et sans doute n'est pas nécessaire pour l' library() de la fonction, mais c'est incroyablement puissant code lorsque vous avez besoin de spécifier des calculs sur des trames de données, comme c'est le cas dans ggplot2 ou dans dplyr, par exemple.

5voto

Ernest A Points 1075

Les lignes

library(ggplot2)
library("ggplot2")

ne sont pas équivalentes. Dans la première ligne, ggplot2 est un symbole, qui peut ou ne peut pas être lié à une certaine valeur. Dans la deuxième ligne, "ggplot2" est un caractère de vecteur de longueur.

Une fonction, cependant, peut manipuler les arguments qu'il obtient sans leur évaluation, et peut décider de traiter les deux cas de manière équivalente, ce qui est le library n'apparemment.

Voici un exemple de la façon de les manipuler non évalué l'expression:

> f <- function(x) match.call()  # return unevaluated function call
> x <- f(foo)
> x
f(x = foo)
> mode(x)
[1] "call"
> x[[1]]
f
> x[[2]]
foo
> mode(x[[2]])
[1] "name"
> as.character(x[[2]])
[1] "foo"
> x <- f("foo")
> mode(x[[2]])
[1] "character"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X