R语⾔笔记7:functions——编写函数所需的基础知识上⼀讲通过三个简单的例⼦体验了⼀下如何在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
> = 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] 4function怎么记忆
这⾥定义函数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 :"
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论