Pregunta

Tengo curiosidad por saber si R puede utilizar su función de eval() para realizar cálculos proporcionados por ejemplo, una cadena.

Este es un caso común:

eval("5+5")

Sin embargo, en lugar de 10 me sale:

[1] "5+5"

Cualquier solución?

¿Fue útil?

Solución

La función eval() evalúa una expresión, pero "5+5" es una cadena, no una expresión. Utilice parse() con text=<string> cambiar la cadena en una expresión:

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

Calling eval() invoca muchos comportamientos, algunos no son inmediatamente obvias:

> 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

TryCatch .

Otros consejos

Puede utilizar la función parse() para convertir los caracteres en una expresión. Es necesario especificar que la entrada es de texto, ya que de análisis espera un archivo por defecto:

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

Lo siento, pero no entiendo por qué muchas personas llegan a pensar una cadena era algo que podría ser evaluada. Debe cambiar su forma de pensar, de verdad. Olvídese de todas las conexiones entre las cuerdas de un lado y expresiones, las llamadas, la evaluación en el otro lado.

El (posiblemente) única conexión es a través de parse(text = ....) y todos los buenos programadores R debe saber que esto no suele ser un medio eficaz o segura para construir expresiones (o llamadas). En lugar de aprender más sobre substitute(), quote(), y, posiblemente, el poder de utilizar 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, aquí es un ejemplo (en los comentarios, no hay ningún formato agradable):

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

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

y si más experiencia usted aprenderá que q5 es un "call" mientras que e5 es un "expression", e incluso que e5[[1]] es idéntica a q5:

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

Como alternativa, puede utilizar evals de mi paquete pander para capturar la salida y todas las advertencias, errores y otros mensajes junto con los resultados primas:

> 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"

Hoy en día también se puede utilizar la función de lazy_eval paquete lazyeval.

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

usando mismo modo rlang:

eval(parse_expr("5+5"))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top