上一讲通过三个简单的例子体验了一下如何在R中写函数,下面来详细学习有关R语言中函数的知识。

Functions in R

主要分三个部分来讲解函数:

  • 编写函数所需的基础知识
  • 相关语法作用域
  • R语言作用域的规则

编写函数所需的基础知识

R语言通过function()指令来命名和创建函数。首先要给函数赋值,也就是命名,然后在小括号中写入参数,最后再大括号中写入函数要执行的语句,其基本语法是:

f <- function(<arguments>){## Do something interesting
}

同时在R中,你可以将函数作为参数传递给其他函数,即嵌套。

函数的返回值是函数执行部分中的最后一行表达式。

编写函数的过程中我们可以设置和命名参数,这些参数可以代表数值、矩阵、数据框或逻辑值等等。同时也可以设置一些具有缺省值(默认值)的参数。

  • 形式参数(formal arguments)

形式参数是包含在函数定义里的参数。

formals()会将一个函数作为输入(input),并返回函数所有的形式参数组成的列表。

在R中,不是所有命令都用到所用的形式参数。加入一个函数中设置了10个参数,但我们往往并不需要指定每个参数的值是啥,所以函数可以缺失某些参数。当没有明确赋值是,它的取值就是缺省值(默认值,default value)

  • 匹配参数(argument matching)

可以根据位置或名称来匹配函数参数,这是编写和调用函数的关键。

以计算数据标准差的函数sd()为例。

> data <- rnorm(100)    ## 取100个符合正态分布的随机数
> sd(x = data)          ## 给参数赋值 求标准差
[1] 1.035329
> sd(data)              ## 给参数默认赋值
[1] 1.035329
> sd(data, na.rm = FALSE)
[1] 1.035329
> sd(na.rm = FALSE, data)  ## 调换参数位置后结果不变
[1] 1.035329

以上所有表达式都是等价的,但是最好不要调换参数位置。

如果函数中参数较多,那么最好使用位置匹配。

比如lm()函数(把数据拟合到线性模型),它的参数列表这么长:

> args(lm)
function (formula, data, subset, weights, na.action, method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, contrasts = NULL, offset, ...)
NULL

前五个参数都没有缺省值,依次是,公式、数据、子集、权重等。这里使用者必须要指定他们的值。

lm(y ~ x, mydata, 1:100, model = FALSE)

大多数情况下,我们不知道参数的具体位置,所以在命令行中,命名参数来匹配最安全。

The order of operations when given an argument is:

  1. Check for exact match for a named argument
  2. Check for a partial match
  3. Check for a positional match
  • 惰性求值(Lazy Evaluation)

惰性求值是R语言的一个关键特性,也是许多编程语言常用的模型。仅在使用函数参数时对其求值。

第一个例子:

> f <- function(a, b) {+         a^2
+ }
> f(2)
[1] 4

这里定义函数f,有两个参数,但返回值仅仅是a的平方。所以当运行f(2)时,和b无关,所以系统自动跳过,不会报错。

第二个例子:

> f <- function(a, b) {
+         print(a)
+         print(b)
+ }
> f(45)
[1] 45
Error in print(b): argument "b" is missing, with no default

这里同样定义f有两个参数,但返回值是a和b,所以当输入f(45)时,因为第二个位置上缺少b的赋值,所以会报错。这里就是用了惰性求值,即,仅在使用这个参数的时候进行求值,在这之前的程序都是有效的并可以执行,直至运行到出错的部分。

  • 特殊参数...

...参数是一种特殊的参数,表明一些可以传递给另一个函数的参数。常用于当你需要扩展另一个函数,而你又不想复制原函数的整个参数列表时。

如下例,你希望修改plot()函数中的个别参数,而其他参数保持不变,将其应用于一个新定义的函数中myplot()

myplot <- function(x, y, type = "l", ...) {plot(x, y, type = type, ...)         ## Pass '...' to 'plot' function
}

在泛型函数(generic function)中,...还有另一种用法,它的作用是根据数据类型使用合适的方法

泛型函数是一个函数族,其中的每个函数都有相似的功能,但是适用于某个特定的类。

> mean
function (x, ...)
UseMethod("mean")
<bytecode: 0x5d5e3e8>
<environment: namespace:base>

还有一种情况下,...参数必须使用:

那就是,当传递到函数的参数数量不能事先确定的时候。

比如paste()函数,他的作用是将一连串字符串连接起来,然后新建一个字符串或向量,所以无法预知参数个数:

> args(paste)
function (..., sep = " ", collapse = NULL)
NULL

还有cat()函数,它的功能是和paste相似,也是连接字符串。

> args(cat)
function (..., file = "", sep = " ", fill = FALSE, labels = NULL, append = FALSE)
NULL

使用...函数的一个注意事项:

就是任何出现在...之后的参数列表必须明确的给出名称。而且不能够部分匹配或位置匹配

举例:

> paste("a","b",sep = ":")
[1] "a:b"

不能位置匹配或部分匹配:

> paste("a","b",":")
[1] "a b :"
> paste("a","b",se = ":")
[1] "a b :"

参考资料:
1. 视频课程 R Programming by Johns Hopkins University:https://www.coursera.org/learn/r-programming/home/welcome
2. 讲义 Programming for Data Science :https://bookdown.org/rdpeng/rprogdatascience/R

R语言笔记7:functions——编写函数所需的基础知识相关推荐

  1. R语言学习丨数据重塑、拆分与组合基础知识,merge、melt、cast函数介绍

    今天学习R语言中数据重塑相关基础知识,主要有merge.melt.cast函数用法示例.公众号:生信分析笔记 合并数据框 merge()函数能够以一列为参考合并两个不同数据框,相当于数学中的布尔运算& ...

  2. R语言笔记2:读写数据所需的主要函数、与外部环境交互

    R语言基础系列前情提要: - 1数据类型(向量.数组.矩阵. 列表和数据框) Getting Data In and Out of R (一)读取数据 读取数据所需的几种函数: read.table. ...

  3. R语言笔记-日期/时间处理函数

    1.获取当前日期/时间 获取日期 > Sys.Date() [1] "2017-02-24" 注意:在R中日期实际是double类型,是从1970年1月1日以来的天数 获取时 ...

  4. R语言笔记6:在R中写一些简单的函数、functions基础和作用域

    R语言基础系列: 1数据类型(向量.数组.矩阵. 列表和数据框) 2读写数据所需的主要函数.与外部环境交互 3数据筛选--提取对象的子集 4向量.矩阵的数学运算 5控制结构 Your first R ...

  5. R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(编写自定义函数添加均值、标准偏差)实战

    R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(编写自定义函数添加均值.标准偏差)实战 目录 R语言使用ggplot2包geom_jitte ...

  6. predict函数 R_学习|R语言做机器学习的常用函数总结

    预测函数:predict() type="prob"判别该量度的昆虫归类为A.B和C的概率:type="response":判别该量度的昆虫的类别: 预测分类的 ...

  7. C语言设计函数求最大公约数,C语言程序设计课程设计--编写函数求取两个整数m,n的最大公约数和最小公倍数.doc_在线文库www.lddoc.cn...

    C语言程序设计课程设计--编写函数,求取两个整数m,n的最大公约数和最小公倍数.doc C语言程序设计课程设计C语言程序设计课程设计评语考勤(10)纪律(10)过程(40)设计报告(30)答辩(10) ...

  8. R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(添加箱图、带缺口的小提琴图、小提琴图)实战

    R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(添加箱图.带缺口的小提琴图.小提琴图)实战 目录 R语言使用ggplot2包geom_jit ...

  9. R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(颜色配置:连续色彩、离散色彩、色彩梯度)实战

    R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(颜色配置:连续色彩.离散色彩.色彩梯度)实战 目录 R语言使用ggplot2包geom_ji ...

最新文章

  1. Python,OpenCV使用KNN来构建手写数字及字母识别OCR
  2. Spring+Hibernate项目在weblogic中部署的一些问题
  3. jdbc连接操作mysql,直接操作和预处理方式
  4. prometheus监控_使用Prometheus和Grafana监视开放自由
  5. 03-spring bean
  6. 万字长文浅析SpringCould微服务负载均衡框架Ribbon源码(字多慎入)
  7. Win下通过 Navica t连接Ubuntu下MySQL数据库
  8. linux脚本获取usb设备,Linux基于USB端口执行脚本
  9. 什么是GaussDB
  10. 转-squid介绍及其简单配置
  11. 极易的je-analysis-1.5.3.jar 可与 solr 一起使用 http://www.jesoft.cn/
  12. ASP.NET的Session会导致的性能问题
  13. “华硕zx50j,键盘背光灯无法显示,fn组合键不可用”解决办法
  14. 服务器asc文件怎么打开,ASC文件扩展名 - 什么是.asc以及如何打开? - ReviverSoft...
  15. 无人驾驶入门1:无人驾驶概览
  16. 电力工程项目管理系统
  17. 威金敌敌畏--比特解决威金方案(转)
  18. Java 面向对象(一)
  19. 关于如何让模拟器(包括虚拟机哦) 更加流畅
  20. scandir函数详解

热门文章

  1. 计算机设备型号和序列号,怎么查看计算机型号_怎么查看计算机序列号
  2. GL音乐播放器1.0.0版-- 总结帖
  3. 使用决策树预测大盘指数
  4. 回归综合案例——利用回归模型预测鲍鱼年龄
  5. 读论文|基于大平面物体垂直姿态的双向人机双手交接
  6. LINUX学记笔记17
  7. 龚文祥:VC看B2C的5个核心数据
  8. 羲云社区团购微信小程序 活动详细页 (界面及功能设计)
  9. 程序员幽默搞笑文章,很有意思!大家一起放松一下!!
  10. 常用搜索引擎使用技巧