Avaliar expressão dada como uma string

Estou curioso para saber se R pode usar sua function eval() para executar cálculos fornecidos, por exemplo, por uma string.

Este é um caso comum:

 eval("5+5") 

No entanto, em vez de 10, recebo:

 [1] "5+5" 

Qualquer solução?

A function eval() avalia uma expressão, mas "5+5" é uma string, não uma expressão. Use parse() com text= para alterar 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" 

Chamar 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 .

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

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

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

A (possivelmente) única conexão é via parse(text = ....) e todos os bons programadores R devem saber que isso raramente é um meio eficiente ou seguro de construir expressões (ou chamadas). Em vez disso, aprenda 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) 

Dec.2017: Ok, aqui está um exemplo (nos comentários, não há formatação legal):

 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á que q5 é uma "call" enquanto e5 é uma "expression" , e mesmo que e5[[1]] é idêntico a q5 :

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

Como alternativa, você pode usar evals do meu pacote pander para capturar a saída e todos os avisos, erros e outras mensagens junto 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 a function lazyeval pacote lazyeval .

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