2 min read

NSE in R 理解

NSE

NSE,全名Non-Standard Evaluation,是有关R的编程和参数设计的。

NSE is particularly useful for functions when doing interactive data analysis because it can dramatically reduce the amount of typing. (Wickham 2015)

正如 Wickham (2015) 所说,这提高了编程的效率、节约时间。

举一个python的例,假设一个pd.DataFrame命名为df,有变量xy,假设我们要创造变量z,满足

\[z = x + y\]

通常我们的做法是

df["z"] = df.x + df.y

或者

df["z"] = df["x"] + df["y"]

我们必须在全局环境(global environment)下,特指是dfxy

但是R的情况下,我们可以直接指定对象df,在其 局部环境(local environment)下,进行z = x+y的设定,这就大大提高了我们编程的效率。

mtcars$z <- with(df,x + y)

symbol or string?

与NSE相关的一个问题是,变量设定为 symbol还是 string。 在python里面,面临的问题是,取用x时是,df.x(symbol)还是df["x"](string)。 如果读者有定的使用经验会知道,大多数常用语言,会在symbol的情况下,用tab键进行提示,大大提高我们的编程效率,然而string格式是很难办到的。 RStudio尝试进行一定的Rproj文件夹的索引,但是效果不好。

那么怎么才能使得大多数的string变量变成symbol变量,从而享受tab键带来的便捷呢? 这就需要使用 R Core Team (2017) 的两个函数

  • substitute
  • deparse

它们是组合使用的,因此我先出效果,然后陆续解释每个函数的意义。

symbol_transform <- function(x){deparse(substitute(x))}
symbol_transform(sample.csv)
## [1] "sample.csv"

可以看到sample.csv是一个symobol变量,我使用symbol_transform函数后,就可以反馈成"sample.csv"格式,这样就可以作为read_csvwrite_csv函数的参数了,不需要提前string化。 带来的便利是,例如,我们可以直接samp,按tab键进行联想输入,提高我们的效率。 下次我们写路径的时候不需要写引号了。

下面解释两个函数的意义。

substitute

这个函数是意义是反馈表达式,但不反馈值,为了方便大家理解,我给出一个例子,如果我在R中输入1+3,那么一定会反馈4,但是substitute函数下,只会返回1+3这个表达式。

1+3
## [1] 4
substitute(1+3)
## 1 + 3

deparse

deparse: Turn unevaluated expressions into character strings (R Core Team 2017).

deparse函数使得表达式string化。

1+3
## [1] 4
substitute(1+3)
## 1 + 3
deparse(substitute(1+3))
## [1] "1 + 3"

因此两个函数的组合,可以让我们

通过tab联想进行快速写出表达式, substitute控制表达式,不反馈值 (Elias and Bolker 2015)deparse将表达式string化,方便进入参数要求string的函数中 (Elias and Bolker 2015)

NSE的相关阅读详见, Wickham (2018), Wickham (2017), 藏锋者 (2016)

dplyr

dplyr used to offer twin versions of each verb suffixed with an underscore. These versions had standard evaluation (SE) semantics: rather than taking arguments by code, like NSE verbs, they took arguments by value. Their purpose was to make it possible to program with dplyr. However, dplyr now uses tidy evaluation semantics. NSE verbs still capture their arguments, but you can now unquote parts of these arguments. This offers full programmability with NSE verbs. Thus, the underscored versions are now superfluous. (Wickham et al. 2017)

dplyr包是 Wickham et al. (2017) 设计的,同时考虑了 symbol和 string两种情况,因此非常方便。 函数构建的思路为

  • *_: string,如mutate_
  • *: symbol,如mutate

参考文献

Elias, Joran, and Ben Bolker. 2015. “Pass a Data.frame Column Name to a Function.” 2015. https://stackoverflow.com/questions/2641653/pass-a-data-frame-column-name-to-a-function.

R Core Team. 2017. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.

Wickham, Hadley. 2015. Advanced R. CRC Press.

———. 2017. “Non-Standard Evaluation.” 2017. http://adv-r.had.co.nz/Computing-on-the-language.html.

———. 2018. “Non-Standard Evaluation.” 2018. http://adv-r.had.co.nz/Computing-on-the-language.html.

Wickham, Hadley, Romain Francois, Lionel Henry, and Kirill Müller. 2017. Dplyr: A Grammar of Data Manipulation. https://CRAN.R-project.org/package=dplyr.

藏锋者. 2016. “R语言非标准化求值(Non-Standard Evaluation, Nse).” 2016. https://blog.csdn.net/tanzuozhev/article/details/50603507.