Pergunta

Estou curioso para saber se r pode usar seu eval() função para executar os cálculos fornecidos por uma sequência.

Este é um caso comum:

eval("5+5")

No entanto, em vez de 10, eu entendo:

[1] "5+5"

Qualquer solução?

Foi útil?

Solução

o eval() função avalia uma expressão, mas "5+5" é uma corda, não uma expressão. Usar parse() com text=<string> Para mudar a string em uma expressão:

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

Chamando eval() Invoca muitos comportamentos, alguns não são imediatamente óbvios:

> 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

Veja também trycatch.

Outras dicas

Você pode usar o parse() função para converter os caracteres em uma expressão. Você precisa especificar que a entrada é o texto, porque Parse espera um arquivo por padrão:

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

Desculpe, mas não entendo por que muitas pessoas pensam que uma corda era algo que poderia ser avaliado. Você deve mudar sua mentalidade, realmente. Esqueça todas as conexões entre cordas de um lado e expressões, chamadas, avaliação do outro lado.

A (possivelmente) a conexão é via parse(text = ....) E todos os bons programadores R devem saber que raramente são meios eficientes ou seguros para construir expressões (ou chamadas). Em vez de aprender mais sobre substitute(), quote(), e possivelmente o poder de usar 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)

Dez.2017: OK, aqui está um exemplo (em comentários, não há uma boa formatação):

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

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

E se você ficar mais experiente, aprenderá isso q5 é um "call" enquanto e5 é um "expression", e até que e5[[1]] é idêntico a q5:

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

Alternativamente, você pode usar evals do meu pander Pacote para capturar a saída e todos os avisos, erros e outras mensagens, juntamente com os resultados brutos:

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

Hoje em dia você também pode usar lazy_eval função de lazyeval pacote.

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

Da mesma forma usando rlang:

eval(parse_expr("5+5"))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top