[R]在dplyr基础上编写函数-(2)substitute和quote
关于这两个函数,官方是这么定义的:
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的更多相关文章
- [R]在dplyr基础上编写函数-(1)eval
tidyverse系列的R包虽然解放了大家的双手,但同时也束缚了我们重新编写函数的能力.在这一套语法中,要实现作为函数参数的字符串和变量之间的相互转换困难重重,但只要掌握了其中原理后,也就能够游刃有余 ...
- [R]在dplyr函数的基础上编写函数-(3)tidyeval
dplyr的优点很明显,数据框操作简洁,如filter(df, x == 1, y == 2, z == 3)等于df[df$x == 1 & df$y ==2 & df$z == 3 ...
- python 基础篇 11 函数进阶----装饰器
11. 前⽅⾼能-装饰器初识本节主要内容:1. 函数名的运⽤, 第⼀类对象2. 闭包3. 装饰器初识 一:函数名的运用: 函数名是一个变量,但他是一个特殊变量,加上括号可以执行函数. ⼆. 闭包什么是 ...
- [3]R语言在数据处理上的禀赋——par参数详解(一)
本文目录 公共参数列表 par 颜色相关 字体相关 字体大小相关 线条相关 符号相关 线条和符号大小相关 结束 本文首发:program-dog.blogspot.com 注1:本文也曾在csdn发布 ...
- R语言编程艺术(3)R语言编程基础
本文对应<R语言编程艺术> 第7章:R语言编程结构: 第9章:面向对象的编程: 第13章:调试 ============================================== ...
- Dubbo入门到精通学习笔记(二十):MyCat在MySQL主从复制的基础上实现读写分离、MyCat 集群部署(HAProxy + MyCat)、MyCat 高可用负载均衡集群Keepalived
文章目录 MyCat在MySQL主从复制的基础上实现读写分离 一.环境 二.依赖课程 三.MyCat 介绍 ( MyCat 官网:http://mycat.org.cn/ ) 四.MyCat 的安装 ...
- Go-语言基础-变量-类型-函数
第一个程序 //单行注释 /* 多行注释 */ package main // 表示当前go文件属于main包 import "fmt" // 导入包 //编译型语言需要有一个入口 ...
- python基础之内置函数
该博客内容参考http://www.cnblogs.com/wupeiqi/articles/4943406.html 内置函数 一 详细见python文档,猛击这里 文件操作 操作文件时,一般需要经 ...
- python基础——内置函数
python基础--内置函数 一.内置函数(python3.x) 内置参数详解官方文档: https://docs.python.org/3/library/functions.html?highl ...
随机推荐
- 什么是Sprint计划?
Sprint 计划是Scrum框架中的一个事件,团队将确定他们将在冲刺期间处理的产品积压项目,并讨论他们完成这些产品积压项目的初始计划. 团队可能会发现建立冲刺目标很有帮助,并以此为基础确定他们在冲刺 ...
- Linux入门需要搞清楚的思路问题
很多同学接触linux不多,对linux平台的开发更是一无所知. 而现在的趋势越来越表明,作为一个优秀的软件开发人员,或计算机it行业从业人员,="" 掌握linux是一种很重要的 ...
- insertion-sort-list leetcode C++
Sort a linked list using insertion sort. C++ /** * Definition for singly-linked list. * struct ListN ...
- Docker的centos镜像内无法使用systemctl命令的解决办法
在Docker官方的centos镜像内无法使用systemctl命令的解决办法, 使用该命令docker报错 Failed to get D-Bus connection: Operation not ...
- IDM使用教程:利用IDM下载百度网盘文件
IDM是什么 其实我使用IDM下载器只是为了方便网页版百度网盘直接下载大于40M文件而已,大家知道文件过大必须打开客户端才能下载,这点对于我的破电脑感觉很烦躁,每次要等待它慢悠悠打开,然后动用我的超级 ...
- Redis源码分析(intset)
源码版本:4.0.1 源码位置: intset.h:数据结构的定义 intset.c:创建.增删等操作实现 1. 整数集合简介 intset是Redis内存数据结构之一,和之前的 sds. skipl ...
- spark搭建
1.上传解压,配置环境变量 配置bin目录 2.修改配置文件 conf cp spark-env.sh.template spark-env.sh 增加配置 export SPARK_MASTER_I ...
- Emmet语法 —— 快速生成HTML结构
快速生成HTML结构语法 1.生成单个标签 : 标签名+tab,比如 div 然后tab 键, 就可以生成 <div></div> 2.生成多个相同标签 div*3 + tab ...
- 浅谈springboot自动配置原理
前言 springboot自动配置关键在于@SpringBootApplication注解,启动类之所以作为项目启动的入口,也是因为该注解,下面浅谈下这个注解的作用和实现原理 @SpringBootA ...
- [python]django rest framework写POST和GET接口
版本声明 python3.6.5 Django-2.0.6 djangorestframework-3.8.2 mysqlclient-1.3.12 1.写一个登录接口,不多说,直接上代码 login ...