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

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.

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

  1. > x <- 1
  2. > substitute(x)
  3. x
  4. > quote(x)
  5. x

这样看好像没什么区别。

  1. f <- function(argX) {
  2. list(quote(argX), substitute(argX), argX)
  3. }
  4. suppliedArgX <- 100
  5. f(argX = suppliedArgX)
  6. # [[1]]
  7. # argX
  8. #
  9. # [[2]]
  10. # suppliedArgX
  11. #
  12. # [[3]]
  13. # [1] 100

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

不好理解,再举个例子:

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

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

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

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

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

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

  1. > cyl
  2. Error: object 'cyl' not found

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

  1. > substitute(cyl, mtcars)
  2. [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. 封装一个的toast弹出框(vue项目)

    逆风的方向,更适合飞翔 实现效果 实现步骤 先写出一个toast组件 // Toast.vue <template> <div id="toast" :class ...

  2. Java:死锁编码及定位分析

    Java:死锁编码及定位分析 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 概念 死锁是指两个或多个以上的进程在执行过程中,因争夺资源而造成一种互相等待的现象, ...

  3. BUAA_2019_OO_第一单元总结

    一.基于度量来分析自己的程序结构 1.第一次作业 1.1类图: 第一次作业由于比较简单,我采用了面向过程的编程方式.在Polynomail类的构造函数中将项直接求导输出.这样的弊端显而易见,不能进行优 ...

  4. Kubernetes集群环境搭建全过程

    资源准备以及服务器初始化 所有服务器执行一下脚本进行配置信息初始化: #!/bin/bash cd `dirname $0` # 关闭selinux setenforce 0 sed -i '/SEL ...

  5. noip模拟11

    T1 math 就挺水一小破题目,第一眼看好像不可做,看着看着突然发现假设x和y的最大公约数是gcd,那么kx%y一定是gcd的倍数, 然后想到可以把所有数字与k的gcd求出来,打一个完全背包,可是仔 ...

  6. Pytorch中stack()方法的理解

    Torch.stack() 1. 概念 在一个新的维度上连接一个张量序列 2. 参数 tensors (sequence)需要连接的张量序列 dim (int)在第dim个维度上连接 注意输入的张量s ...

  7. DDL数据定义语言

    DDL数据定义语言 (一)概述 DDL(Data Definition Language):数据定义语言,用来定义数据库对象,库.表.列等:创建.删除.修改 库,表结构.主要分为操作数据库的DDL和操 ...

  8. 《手把手教你》系列技巧篇(四十)-java+ selenium自动化测试-JavaScript的调用执行-下篇(详解教程)

    1.简介 在实际工作中,我们需要对处理的元素进行高亮显示,或者有时候为了看清楚做跟踪鼠标点击了哪些元素需要标记出来.今天宏哥就在这里把这种测试场景讲解和分享一下. 2.用法 创建一个执行 JS 的对象 ...

  9. MySQL基础语句(查询)

    students表 id class_id name gender score 1 1 小明 M 90 2 1 小红 F 95 3 1 小军 M 88 4 1 小米 F 73 5 2 小白 F 81 ...

  10. requests之代理的使用

    import requests # 访问url url = 'http://www.baidu.com/s?' # 请求头 headers = { 'User-Agent': 'Mozilla/5.0 ...