[R]在dplyr基础上编写函数(1)eval

tidyverse系列的R包虽然解放了大家的双手,但同时也束缚了我们重新编写函数的能力。在这一套语法中,要实现作为函数参数的字符串和变量之间的相互转换困难重重,但只要掌握了其中原理后,也就能够游刃有余地处理了。

首先要理解基础R中几个重要又易忽略的函数。

eval

Evaluate an (Unevaluated) Expression: 
Evaluate an R expression in a specified environment.

简言之就是:对表达式对象的求值
可以把字符串转化成表达式来执行, 通常eval和parse结合使用,参数 text 等于要转化的字符串。
表达式对象不能如下表示:

eval("5+5") 
[1] "5+5"  #得到的是一个字符串

需要结合parse函数结合text参数来将字符串转化成一个表达式,再进行求值:

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

不仅仅求值,eval能调用很多行为,如函数。

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

当然,现在也有一些方法能一步到位。如lazyeval包的lazy_eval函数:

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

或用rlang

library(rlang)
eval(parse_expr("5+5"))
[1] 10

但我们要清晰地认识到,字符串和表达式两者之间其实是没有任何关系的,这里只是通过parse(text=)连接起来,而parse(text=)的这种方法并不安全,容易出错,应该慎用。我们更多的应该用substitute()quote()函数,接下来我们介绍这两个函数。

Ref: https://stackoverflow.com/questions/1743698/evaluate-expression-given-as-a-string

原文地址:https://www.cnblogs.com/jessepeng/p/11443858.html