关于这两个函数,官方是这么定义的:

substitute returns the parse tree for the (unevaluated) expression expr, substituting any variables bound in env.

quote simply returns its argument. The argument is not evaluated and can be any R expression.

貌似看不懂,看几个例子来帮助理解。

> x <- 1
> substitute(x)
x
> quote(x)
x

这样看好像没什么区别。

f <- function(argX) {
list(quote(argX), substitute(argX), argX)
} suppliedArgX <- 100
f(argX = suppliedArgX)
# [[1]]
# argX
#
# [[2]]
# suppliedArgX
#
# [[3]]
# [1] 100

这时候可以看出两者处理函数的参数是不一样的,quote一直就是它括起的名称,而substitute如果参数名字有赋值,那就是赋值后的。更具体说是这样的:substitute解析每个元素进行替换,如果它不是env中的绑定符号,则保持不变。如果它是一个promise对象,即函数的形式参数或使用delayedAssign函数显式创建的,则promise的表达式替换成该符号。如果它是普通变量,则其值被替换,除非env是.GlobalEnv(全局环境),在这种情况下符号保持不变。

不好理解,再举个例子:

e <- new.env()
assign(x = "a",value = 1,envir = e)
> substitute(a,env = e)
[1] 1 > quote(a)
[1] a

所以substitute有两种情况会发生名字的替换:一是在函数的参数中应用它时,二是当环境是非.GlobalEnv时。

expr <- quote(x + y)
print(expr) # x + y
eval(expr, list(x = 1, y = 2)) # 3 expr <- substitute(x + y, list(x = 1))
print(expr) # 1 + y
eval(expr, list(y = 2)) # 3

说了半天,这和dplyr函数有什么关系呢?

因为R是惰性求值,对变量名的定义不像其他语言那么清晰。如

dplyr::summarise(mtcars, total_cyl = sum(cyl))中summarise和sum都是函数,mtcars是数据集,那么cyl是啥?

> cyl
Error: object 'cyl' not found

运行直接找不到。因为cyl没有被立刻评价,它像一个表达式对待随后被解析树解析,如果用substitue就可被解析出来。

> substitute(cyl, mtcars)
[1] 6 6 4 6 8 ...

根据quote和substitute我们可以以数据框列名为对象作为参数进行函数的编写,这种编写方式是非常符合人类正常思维的。我们下期再讲。

Ref: https://stackoverflow.com/questions/46834655/whats-the-difference-between-substitute-and-quote-in-r

[R]在dplyr基础上编写函数-(2)substitute和quote的更多相关文章

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

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

  2. [R]在dplyr函数的基础上编写函数-(3)tidyeval

    dplyr的优点很明显,数据框操作简洁,如filter(df, x == 1, y == 2, z == 3)等于df[df$x == 1 & df$y ==2 & df$z == 3 ...

  3. python 基础篇 11 函数进阶----装饰器

    11. 前⽅⾼能-装饰器初识本节主要内容:1. 函数名的运⽤, 第⼀类对象2. 闭包3. 装饰器初识 一:函数名的运用: 函数名是一个变量,但他是一个特殊变量,加上括号可以执行函数. ⼆. 闭包什么是 ...

  4. [3]R语言在数据处理上的禀赋——par参数详解(一)

    本文目录 公共参数列表 par 颜色相关 字体相关 字体大小相关 线条相关 符号相关 线条和符号大小相关 结束 本文首发:program-dog.blogspot.com 注1:本文也曾在csdn发布 ...

  5. R语言编程艺术(3)R语言编程基础

    本文对应<R语言编程艺术> 第7章:R语言编程结构: 第9章:面向对象的编程: 第13章:调试 ============================================== ...

  6. Dubbo入门到精通学习笔记(二十):MyCat在MySQL主从复制的基础上实现读写分离、MyCat 集群部署(HAProxy + MyCat)、MyCat 高可用负载均衡集群Keepalived

    文章目录 MyCat在MySQL主从复制的基础上实现读写分离 一.环境 二.依赖课程 三.MyCat 介绍 ( MyCat 官网:http://mycat.org.cn/ ) 四.MyCat 的安装 ...

  7. Go-语言基础-变量-类型-函数

    第一个程序 //单行注释 /* 多行注释 */ package main // 表示当前go文件属于main包 import "fmt" // 导入包 //编译型语言需要有一个入口 ...

  8. python基础之内置函数

    该博客内容参考http://www.cnblogs.com/wupeiqi/articles/4943406.html 内置函数 一 详细见python文档,猛击这里 文件操作 操作文件时,一般需要经 ...

  9. python基础——内置函数

    python基础--内置函数  一.内置函数(python3.x) 内置参数详解官方文档: https://docs.python.org/3/library/functions.html?highl ...

随机推荐

  1. 利用 pip 安装 Python 程序包到个人用户文件夹下

    利用 --user 参数,即 pip install --user package_name 这样会将Python 程序包安装到 $HOME/.local 路径下,其中包含三个字文件夹:bin,lib ...

  2. UltraSoft - Beta - Postmortem事后分析

    UltraSoft - Beta - PostMORTEM 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 解决的问题和定义都在[软软软]功能规格说明书 ...

  3. python doc os 参考

    os --- 操作系统接口模块 源代码: Lib/os.py 该模块提供了一些方便使用操作系统相关功能的函数. 如果你是想读写一个文件,请参阅 open(),如果你想操作路径,请参阅 os.path  ...

  4. 反转单词顺序列 牛客网 剑指Offer

    反转单词顺序列 牛客网 剑指Offer 题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但 ...

  5. P2774 方格取数问题(最小割)

    P2774 方格取数问题 一看题目便知是网络流,但由于无法建图.... 题目直说禁止那些条件,这导致我们直接建图做不到,既然如此,我们这是就要逆向思维,他禁止那些边,我们就连那些边. 我们将棋盘染色, ...

  6. 用C++实现的数独解题程序 SudokuSolver 2.7 及实例分析

    引言:一个 bug 的发现 在 MobaXterm 上看到有内置的 Sudoku 游戏,于是拿 SudokuSolver 求解,随机出题,一上来是个 medium 级别的题: 073 000 060 ...

  7. C语言的“隐式函数声明”违背了 “前置声明” 原则

    这个问题来源于小组交流群里的一个问题: 最终问题落脚在 : 一个函数在main中调用了,必须在main之前定义或者声明吗? 我在自己的Centos上做了实验,结果是函数不需要,但是结构体(变量也要)需 ...

  8. Git 图形化客户端--Sourcetree

    1.图形化客户端: sourcetre下载:https://www.sourcetreeapp.com/ 2.接着并执行SourceTreeSetup-3.1.3.exe,会进入登录或注册bitbuc ...

  9. Jenkins 邮件发送

    1.jenkins新建任务 2.配置svn 3.maven项目构建配置pom.xml 使用maven命令 clean test 构建前清除: 4.系统管理 => 插件管理 =>可选安装邮件 ...

  10. 为何我中断执行的线程不起作用,Why

    摘要:我们就以一个案例的形式,来为大家详细介绍下为何中断执行的线程不起作用. 本文分享自华为云社区<明明中断了线程,却为何不起作用呢?>,作者:冰 河. 当我们在调用Java对象的wait ...