-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmp-introduction.Rmd
35 lines (24 loc) · 3.45 KB
/
mp-introduction.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# (PART) 元编程 {-}
# 元编程概述 {#mp-intro .unnumbered}
```{r, include = FALSE}
source("common.R")
```
R语言中最令人好奇的能力莫过于**元编程**,这是一种将代码视为可以被检查与修改数据的编程范式。这是一种非常重要的思想,对很多R语言代码产生了深远的影响。
元编程的一些基础用法是可以让您输入类似于`library(purrr)`这样的代码来代替原本应该输入的`library("purrr")`,或者在使用`plot(x,sin(x))`画图时
自动将您的坐标轴名称标记为`x`与`sin(x)`。而更深高级的用法中,它允许您使用`y ~ x1 + x2`这样的公式来表示一个可以通过`x1`与`x2`预测出`y`的模型,
可以将`subset(df, x == y)`转换为`df[df$x == df$y, , drop = FALSE]`,使用`dplyr::filter(db, is.na(x))`去生成一条`x is NULL`,
`db`是一张远程数据表的SQL语句。
与元编程密切相关的是**非标准化求值**,简称NSE。这个术语通常被用于描述R函数的行为,但存在两方面的问题。首先NSE实际是函数参数的属性值,因此说“NSE函数”
是有一些不够严谨的。其次,用一个不是标准的东西定义其他概念是令人费解的,因此在这本书中我将介绍更为精准的词汇表达。
具体来说,这本书侧重于tidy风格的计算,这种计算风格在rlang[@rlang]包中实现,在与元编程相关章节中,我将会大量使用rlang。这使得您可以专注于重要的思想,
不会被R语言历史中出现的怪异实现所困扰。在我用rlang介绍了每个重要的思想之后,我会回过头来解释它们在R基础包中的表现。这种方法对于一些读者而言似乎很落后,
但就像我们学习驾驶自动档汽车代替手动档一样,它可以使您在了解细节之前专注于全局。本书侧重于tidy计算方面的理论,您可以从头开始完全理解它的工作原理。如果您
正在寻找更实用的介绍文档,我推荐您阅读tidy计算方面的书籍 <https://tidyeval.tidyverse.org>[^tidyeval-wip]。
[^tidyeval-wip]: 在我写这一章的时候,tidy计算相关书籍还在编写中,但当您读到这本书时,它有望完成。
您将从接下来的五章中学到元编程与tidy计算方面的知识:
1. 第\@ref(bigpicture)章对于整个元编程进行了更高层次的概述,简要介绍了所有主要组件以及它们如何结合在一起形成一个有机的整体。
1. 第\@ref(expressions)章介绍R语言代码如何被描述为一个树型结构。您将学习如何可视化这些树,R语言的语法规则如何将这些线性字符序列转换为树,以及如何使用递归函数处理代码树。
1. 第\@ref(quasi)章介绍了rlang中的一些工具,您可以使用它们去捕获未计算函数的参数。您同时可以学习反引用的相关知识,它提供一组取消引用输入的技术,使得从代码片段生成代码树成为可能。
1. 第\@ref(evaluation)章介绍了如何计算捕获的代码,在这里您将了解到一个重要的数据结构`quosure`,它通过捕获需要计算的代码和所处的环境信息,来确保计算的准确性。
本节将把上述所有知识点整合起来,以介绍NSE在R基础包中是如何工作的,同时了解如何写出类似于`subset()`这样工作的函数。
1. 第\@ref(translating)章结合了环境、语法作用域和元编程的知识向您介绍如何将R代码翻译为类似于HTML和LaTeX这样的语言。