Question

Je suis curieux de savoir si R peut utiliser sa fonction eval() pour effectuer des calculs fournis par exemple une chaîne.

Ceci est une affaire commune:

eval("5+5")

Cependant, au lieu de 10, je reçois:

[1] "5+5"

Toute solution?

Était-ce utile?

La solution

La fonction eval() évalue une expression, mais "5+5" est une chaîne, pas une expression. Utilisez parse() avec text=<string> pour changer la chaîne en une expression:

> eval(parse(text="5+5"))
[1] 10
> class("5+5")
[1] "character"
> class(parse(text="5+5"))
[1] "expression"

Calling eval() invoque de nombreux comportements, certains ne sont pas évidents:

> class(eval(parse(text="5+5")))
[1] "numeric"
> class(eval(parse(text="gray")))
[1] "function"
> class(eval(parse(text="blue")))
Error in eval(expr, envir, enclos) : object 'blue' not found

Voir aussi TryCatch .

Autres conseils

Vous pouvez utiliser la fonction parse() pour convertir les caractères en une expression. Vous devez spécifier que l'entrée est du texte, car Parse attend un fichier par défaut:

eval(parse(text="5+5"))

Désolé, mais je ne comprends pas pourquoi trop de gens pensent même une chaîne était quelque chose qui pourrait être évalué. Vous devez changer votre état d'esprit, vraiment. Oubliez toutes les connexions entre les chaînes d'un côté et les expressions, les appels, l'évaluation de l'autre côté.

Le (peut-être) que la connexion se fait via parse(text = ....) et tous les bons programmeurs R devrait savoir que cela est rarement un moyen efficace ou sans danger pour construire des expressions (ou appels). apprendre plutôt plus sur substitute(), quote(), et peut-être le pouvoir d'utiliser do.call(substitute, ......).

fortunes::fortune("answer is parse")
# If the answer is parse() you should usually rethink the question.
#    -- Thomas Lumley
#       R-help (February 2005)

Dec.2017: Ok, voici un exemple (dans les commentaires, il n'y a pas belle mise en forme):

q5 <- quote(5+5)
str(q5)
# language 5 + 5

e5 <- expression(5+5)
str(e5)
# expression(5 + 5)

et si vous êtes vous plus expérimenté apprendrez que q5 est un "call" alors e5 est un "expression", et même que e5[[1]] est identique à q5:

identical(q5, e5[[1]])
# [1] TRUE

Vous pouvez utiliser evals de mon paquet pander pour capturer la sortie et tous les avertissements, erreurs et autres messages ainsi que les résultats bruts:

> pander::evals("5+5")
[[1]]
$src
[1] "5 + 5"

$result
[1] 10

$output
[1] "[1] 10"

$type
[1] "numeric"

$msg
$msg$messages
NULL

$msg$warnings
NULL

$msg$errors
NULL


$stdout
NULL

attr(,"class")
[1] "evals"

De nos jours, vous pouvez également utiliser la fonction lazy_eval du paquet lazyeval.

> lazyeval::lazy_eval("5+5")
[1] 10

De même en utilisant rlang:

eval(parse_expr("5+5"))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top