在R语言的绘图函数中,如果文本参数是合法的R语言表达式,那么这个表达式就被用Tex类似的规则进行文本格式化。

y <- function(x) (exp(-(x^2)/2))/sqrt(2*pi)plot(y, -5, 5, main = expression(f(x) == frac(1,sqrt(2*pi))*e^(-frac(x^2,2))), lwd = 3, col = "blue")

library(ggplot2)x <- seq(0, 2*pi, by = 0.01)
y <- sin(x)
data <- data.frame(x, y)
p <- ggplot(data, aes(x, y)) + geom_line()p + geom_area(fill = 'blue', alpha = 0.3) +scale_x_continuous(breaks = c(0, pi, 2*pi), labels = c('0', expression(pi), expression(2*pi))) +geom_text(parse = T, aes(x = pi/2,y = 0.3, label = 'integral(sin(x)*dx, 0, pi)'))

##一、R语言的“表达式”

  在R语言中,“表达式”的概念有狭义和广义两种意义。狭义的表达式指表达式(expression)类对象,由expression函数产生;而广义的的表达式既包含expression类,也包含R“语言”类(language)。expression和language是R语言中两种特殊数据类:

getClass(“expression”)

# Class "expression" [package "methods"]# No Slots, prototype of class "expression"# Extends: "vector"

getClass(“language”)

# Virtual Class "language" [package "methods"]# No Slots, prototype of class "name"# Known Subclasses:
# Class "name", directly
# Class "call", directly
# Class "{", directly
# Class "if", directly
# Class "<-", directly
# Class "for", directly
# Class "while", directly
# Class "repeat", directly
# Class "(", directly
# Class ".name", by class "name", distance 2, with explicit coerce

可以看到expression类由向量派生得到,而language类是虚拟类,它包括我们熟悉的程序控制关键词/符号和name、call 子类。

##二、产生“表达式”的函数

虽然我们在R终端键入的任何有效语句都是表达式,但这些表达式在输入后即被求值(evaluate)了,获得未经求值的纯粹“表达式”就要使用函数。下面我们从函数参数和返回值两方面了解expression、quote、bquote和substitute这几个常用函数。

####1、expression 函数

expression函数可以有一个或多个参数,它把全部参数当成一个列表,每个参数都被转成一个表达式向量,所以它的返回值是表达式列表,每个元素都是表达式类型对象,返回值的长度等于参数的个数:

(ex <- expression(x = 1, 1 + sqrt(a)))## expression(x = 1, 1 + sqrt(a))length(ex)## [1] 2ex[1]## expression(x = 1)mode(ex[1])## [1] "expression"typeof(ex[1])## [1] "expression"ex[2]## expression(1 + sqrt(a))mode(ex[2])## [1] "expression"typeof(ex[2])## [1] "expression"

因为expression函数把参数当成列表处理,所以等号‘=’两边的表达式要符合R语言列表元素的书写规则,否则出错,比如:

expression(x+11=1)

####2、quote函数

quote函数只能有一个参数。quote函数的返回值一般情况下是call类型,表达式参数是单个变量的话返回值就是name类型,如果是常量那么返回值的存储模式就和相应常量的模式相同:

(cl <- quote(1 + sqrt(a) + b^c))
## 1 + sqrt(a) + b^cmode(cl)
## [1] "call"typeof(cl)
## [1] "language"(cl <- quote(a))
## amode(cl)
## [1] "name"typeof(cl)
## [1] "symbol"(cl <- quote(1))
## [1] 1mode(cl)
## [1] "numeric"typeof(cl)
## [1] "double"

quote返回值如果是name或常量类型,它的长度就是1;如果是call类型,返回值长度就与函数/运算符的参数个数n对应,长度等于n+1,多出的长度1是函数/符号名。

length(quote(a))  #name或常量类型,返回值长度为1
## [1] 1length(quote(!a))  #单目运算符,返回值长度为2
## [1] 2length(quote(-b))  #单目运算符,返回值长度为2
## [1] 2length(quote(a + b))  #双目运算符,返回值长度为3
## [1] 3length(quote((a + b) * c))  #多个运算符只算优先级最低的一个
## [1] 3

####3、bquote 和 substitute 函数

如果不使用环境变量或环境变量参数,bquote 和 substitute 函数得到的结果与quote函数相同。

bquote(1 + sqrt(a) + b^c) == quote(1 + sqrt(a) + b^c)
## [1] TRUEsubstitute(1 + sqrt(a) + b^c) == quote(1 + sqrt(a) + b^c)
## [1] TRUE

但是bquote 和 substitute 函数可以在表达式中使用变量,变量的值随运行进程而被替换。bquote 和 substitute 函数变量替换的方式不一样,bquote函数中需要替换的变量用 .( ) 引用,substitute函数中需要替换的变量用列表参数方式给出。除了这一点,bquote 和 substitute 函数没有差别:

a <- 3b <- 2(bq <- bquote(y == sqrt(.(a), .(b))))
## y == sqrt(3, 2) (ss <- substitute(y == sqrt(a, b), list(a = 3, b = 2)))
## y == sqrt(3, 2) bq == ss
## [1] TRUE

搞出两个功能完全一样的函数不算很奇怪,R语言里面太多了,可能是照顾不同使用习惯的人们吧。bquote函数的帮助档说这个函数类似于LISP的backquote宏,对于像我这样的LISP盲,使用substitute函数好一些。 substitute函数的典型用途是替换表达式中的变量,如果我们希望在表达式中使用变量并且希望这些变量在运行过程中做出相应改变,就可以使用substitute函数。

par(mar = rep(0.1, 4), cex = 2)plot.new()plot.window(c(0, 10), c(0, 1))for (i in 1:9) text(i, 0.5, substitute(sqrt(x, a), list(a = i + 1)))

####4、parse 函数

parse函数用于从文件读取文本作为表达式,返回的值是expression类型,这函数也很有用。后面有例子。

x <- 1x + "x"## Error: 二进列运算符中有非数值参数expression(x + "x")## expression(x + "x")quote(x + "x")## x + "x"

但R要检查表达式中的运算符,不符合运算符使用规则的表达式将出错:

expression(x + +++y)
## expression(x + +++y) expression(x - ---y)
## expression(x - ---y)
## expression(x****y) (Not run) expression(xy) (Not run)
## expression(1<=x<=4) (Not run) quote(x + +++y)
## x + +++y quote(x - ---y)
## x - ---y
## quote(x****y) (Not run) quote(xy) (Not run) quote(1<=x<=4) (Not run)

+ - 运算连续使用不出错是因为它们还可以当成求正/负值运算的符号。 在表达式产生函数中使用paste函数可以解决这样的问题。在这种条件下,paste对参数的处理方式和表达式产生函数一样,检查运算符但不检查变量名。用NULL作为运算符的参数可以获得意外的效果:

ex <- expression(paste(x, "", y))cl <- quote(paste(x, "****", y))par(mar = rep(0.1, 4), cex = 2)plot.new()plot.window(c(0, 1.2), c(0, 1))text(0.2, 0.5, ex)text(0.6, 0.5, cl)cl <- quote(paste(1 <= x, NULL <= 4))text(1, 0.5, cl)

##三、R绘图函数对文本参数中的表达式的处理

quote, bquote 和 substitute 的返回值有三种类型call, name 和 常量,事实上expression 函数的结果最终也是这三种类型。因为expression函数的结果是expression列表,我们取列表元素的值检查看看:

(ex <- expression(1 + sqrt(x), x, 1))
## expression(1 + sqrt(x), x, 1)ex[[1]]
## 1 + sqrt(x)mode(ex[[1]])
## [1] "call"typeof(ex[[1]])
## [1] "language"ex[[2]]
## xmode(ex[[2]])
## [1] "name"typeof(ex[[2]])
## [1] "symbol"ex[[3]]
## [1] 1mode(ex[[3]])
## [1] "numeric"typeof(ex[[3]])
## [1] "double"

确实是这样。所以绘图函数对文本参数中的表达式处理就有三种情况。先看看处理结果:

par(mar = rep(0.1, 4), cex = 2)plot.new()plot.window(c(0, 1.2), c(0, 1))text(0.2, 0.5, ex[1])text(0.6, 0.5, ex[2])text(1, 0.5, ex[3])

name 和常量类型都很简单,直接输出文本,而call类型就不好判断了。我们前面说过call类型返回值的长度与函数/运算符的参数个数有关。这是怎么体现的呢?由于文本参数最终得到的是文本,我们用as.character函数来看看:

as.character(quote(x - y))
## [1] "-" "x" "y"as.character(quote(1 - x + y))
## [1] "+"  "1 - x" "y"as.character(quote((1 + x) * y))
## [1] "*"  "(1 + x)" "y"as.character(quote(!a))
## [1] "!" "a"as.character(quote(sqrt(x)))
## [1] "sqrt" "x"

转换成字符串向量后排在第一位的是运算符或函数名称,后面是参数(如果参数中还有运算符或函数名,R还会对其进行解析)。运算符和函数是相同的处理方式。事实上,在R语言中,所有运算符(包括数学运算符和逻辑运算符)都是函数,你可以用函数的方式使用运算符:

2 + 4
## [1] 62 - 4
## [1] -22 <= 4
## [1] TRUE2 >= 4
## [1] FALSE

R绘图函数对表达式中包含的函数名和它们的参数首先应用Tex文本格式化规则进行处理,这种规则的具体情况可以使用 ?plotmath 进行查看,主要是一些数学公式和符号的表示方法。把这个说明文档中字符串拷贝到maths.txt文件中并保存到当前工作目录后可以用下面的代码做出后面的表格:

ex <- parse("maths.txt")labs <- readLines("maths.txt")n <- length(ex)par(mar = rep(0.1, 4), cex = 0.8)plot.new()plot.window(c(0, 8), c(0, n/4))y <- seq(n/4, by = -1, length = n/4)x <- seq(0.1, by = 2, length = 4)xy <- expand.grid(x, y)text(xy, labs, adj = c(0, 0.5))xy <- expand.grid(x + 1.3, y)text(xy, ex, adj = c(0, 0.5), col = "blue")box(lwd = 2)abline(v = seq(1.3, by = 2, length = 4), lty = 3)abline(v = seq(2, by = 2, length = 3), lwd = 1.5)


右键查看图片,浏览大图

表中奇数列是字符串(表达式),偶数列(蓝色)是Tex格式化的图形。除了上表列出的规则外还有一些拉丁文和希腊文符号,可以在表达式中用 symbol 函数或名称(如alpha)等表示,用到时自己去找吧。 如果函数名(包括运算符)有对应的Tex格式化规则,函数名和参数都按规则进行图形绘制;如果没有,就当成是R语言普通函数:

ex <- expression(sqrt(x), x + y, x^2, x %in% A, x <= y, mean(x, y, z), x | y, x & y)n <- length(ex)par(mar = rep(0.1, 4), cex = 1.5)col <- c("red", "blue")plot.new()plot.window(c(0, n), c(0, 1))for (i in 1:n) text(i - 0.5, 0.5, ex[i], col = col[i%%2 + 1])

上面例子中前5种运算函数都是有对应数学符号的,所以它出的图(符号和顺序)与数学习惯一致,后三种运算函数没有对应数学符号,所以用普通函数方式(函数名在前,参数在括号内用逗号分隔)出图。其他还有一些琐碎的规则,自己找找吧。

本文转自科学网李鹏程博客

欢迎访问我的个人站点:http://bgods.cn/

R语言:表达式、数学公式、特殊符号相关推荐

  1. R语言计算带有绝对值符号的函数偏导并输出偏导结果

    R语言计算带有绝对值符号的函数偏导并输出导数结果 求偏导后的导数表达式网上已有众多教程,这里主要对导数结果的输出及含有绝对值符号的的函数偏导运算进行方法阐述 对函数f=x*|y|*(z-x)求对x.y ...

  2. R语言 表达式对象的求值 eval

    R语言 表达式对象的求值 eval 模式为 "expression"的对象在Expression objects 有具体定义.它们和引用对象的列表非常相似. > ex < ...

  3. R语言中的复制符号-和=

    对一般的赋值语句,"<-" 与 "=" 功能上无区别  ,但通常我们强推"<-". 原因是等号存在二义性:它既可以赋值,也可以传 ...

  4. R语言中按某个符号来分割字符串

    dat2 <- as.character(unlist(strsplit(dat, split = ">"))) END

  5. r语言各形状编号_R语言plot()函数的符号、颜色和尺寸

    龙源期刊网 http://www.qikan.com.cn R 语言 plot() 函数的符号.颜色和尺寸 作者:耿秀华 来源:<数字技术与应用> 2018 年第 10 期 摘 ; 要:本 ...

  6. r语言用行名称提取数据框信息显示na_学会这些R语言技巧至少可以节省半年时间...

    ubuntu备忘定期清空回收站 扩增子数据牢记 r ubuntu 相关技巧和备忘待解决问题1:phyloseq有一篇文章案例使用输入和输出文件相同的文件名,无法执行 待解决问题2: 待解决问题3:样品 ...

  7. r语言 新增一列数字类型_R语言实战之R语言基础语法精讲(一)

    R是用于统计分析.绘图的语言和操作环境.R是属于GNU系统的一个自由.免费.源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具.在学习R数据科学之前,我们首先要对R语言的基础语法有一个良好的了 ...

  8. 初识R语言介绍以及常见的问题

    R语言是用于统计分析,图形表示和报告的编程语言和软件环境. R语言由Ross Ihaka和Robert Gentleman在新西兰奥克兰大学创建,目前由R语言开发核心团队开发. R语言的核心是解释计算 ...

  9. r语言和metawin_学会这些R语言技巧至少可以节省半年时间

    ubuntu备忘 定期清空回收站 扩增子数据牢记 r ubuntu 相关技巧和备忘 待解决问题1:phyloseq有一篇文章案例使用输入和输出文件相同的文件名,无法执行 待解决问题2: 待解决问题3: ...

最新文章

  1. CentOS 7.8下安装完美安装配置Rosetta
  2. 002.iSCSI服务端配置
  3. 网络营销专员浅析在网络营销推广中有不少渠道可适当“利用”一下
  4. c strlen C++ strlen
  5. JDBC连接数据库经验集萃
  6. canoco5冗余分析步骤_打造高性能的大数据分析平台
  7. 大牛手把手教你!2021大厂Java面试经历
  8. 在dos下运行.exe程序(C++)
  9. 论文浅尝 - SWJ | 基于知识图谱和注意力图卷积神经网络的可解释零样本学习
  10. 国科大prml11-降维
  11. windows2016+sqlserver2017集群搭建alwayson之搭建配置篇
  12. 矩阵求导最简单的理解
  13. weblogic故障报错
  14. 3d建模电脑配置要求_专业3d动画建模需要什么配置 运行Blender的电脑配置推荐
  15. spark的集群安装
  16. java运行时数据区(pc寄存器、虚拟机栈(栈帧)、本地方法栈、java堆、方法区、运行时常量池、直接内存)
  17. Ubuntu 使用微信开发者工具
  18. 电源php38电路,六款uc3842开关电源电路图分享
  19. Win10系统安装打印机提示未安装打印机驱动程序,试图将驱动程序添加到存储区
  20. 量化投资之工具篇一:Backtrader从入门到精通(7)-Indicator类源代码解读(2)

热门文章

  1. 珠海到各大机场的线路
  2. 基于LAB颜色空间的彩色图像分割
  3. 宏旺半导体为你解释手机内存不够用的原因
  4. java.util.regex.PatternSyntaxException: Unclosed counted closure near index 14 [0-9a-zA-Z]{1, 20}报错
  5. 计算有效时间的时间戳
  6. 提示BeanPostProcessorChecker:is not eligible for getting processed by all BeanPostProcessors的原因
  7. Excel中按多个符号进行分列
  8. node.js+mysql实现分库分表存查数据:
  9. 16含参数的极限问题
  10. eclipse不自动弹出提示(alt+/快捷键失效)