(R语言)编写自己的函数

来源:互联网 发布:迅雷mac版下载速度是0 编辑:程序博客网 时间:2024/05/16 07:06

10.1 函数的定义

> name <- function(arg_1, arg_2, ...) expression 
expression是一个R表达式(通常是表达式语句组),并使用参数arg_i来计算出一个数值,表达式的值就是函数的返回值。
函数调用的形式通常都是name(expr1,expr2,...)

10.2 定义新的二元操作符

可以将函数定义为新的二元操作符:
> "%!%" <- function(X, y) { ... }
正如矩阵乘法运算符,%*%,和矩阵外积运算符%o%

10.3 指定参数和默认值

如果被调用函数的参数按照"name = obj"的形式给出,那么参数的次序可以是任意的。
而且,参数序列可以在开始依次序给出,而将指定名称的参数置于后面。
因此,如果由一个函数fun1被定义为
> fun1 <- function(data, data.frame, graph, limit) {
[function body omitted]
}
那么函数可以有多种等价的使用方法,例如
> ans <- fun1(d, df, TRUE, 20)
> ans <- fun1(d, df, graph=TRUE, limit=20)
> ans <- fun1(data=d, limit=20, graph=TRUE, data.frame=df)
默认值 :在很多情况下,参数都会被赋予一个普遍适用的默认值。
> fun1 <- function(data, data.frame, graph=TRUE, limit=20) { ... }
则函数可以这样被调用
> ans <- fun1(d, df)
此时与上面三种情况等价,也可以这样调用
> ans <- fun1(d, df, limit=10)
此时改变了一个默认值。
NOTE:参数可以是任意表达式,甚至可以是包含其他参数的表达式;

10.4 额外参数“...”

当需要将一个函数的参数传递给另一个函数时,可以通过包含一个额外的参数"..."实现。
fun1 <- function(data, data.frame, graph=TRUE, limit=20, ...) {
[omitted statements]
if (graph)
par(pch="*", ...)
[more omissions]
}

10.5 全局变量和局部变量

函数内的赋值都是局部变量,退出函数就丢失了。
如果要在函数内进行永久赋值(定义全局变量),需要用到“超赋值”操作符, <<-或者函数assign()。

10.6 一些高级示例

区组设计的效率因子 (E±ciency factors)
删除打印数组中的所有名称
递归的数值积分

10.7 范畴(Scope)

函数主体内出现的标识(symbol)可以被分为3类;正式参数、局部变量和自由变量。
正式参数就是出现在函数参数列表中的参数,他们的值由实际的函数参数与正式参数的绑定(binding)过程决定。
局部变量是在参数主体中,由表达式求值过程决定的变量。
自由变量为既不是正式参数又不是局部变量的变量。赋值之后自由变量成为局部变量。

在R中,自由变量的值由函数被创建的环境中与其同名的第一个变量值决定(我理解为最近的同名变量),这种方式被称为词汇式范畴(lexical scope)。
而在S中,该值由同名的全局变量决定。
例如下面的函数cube,在R中cube(2)=8,在S中报错为sq()找不到n。
cube <- function(n) {
sq <- function() n*n
n*sq()
}

一个银行账户的例子,详见《R语言笔记》。

10.8 定制环境

详见《R语言笔记》。

10.9 类别,通用函数和对象定位

一个对象的类别(class)决定了他会如何被通用函数(generic function)处理。
如果参数本身没有任何类别属性,或者其类别在特定问题中并不满足通用函数的要求,通常会有一个默认的动作被执行。
类别机制使用户可以为特定的目的设计和编写通用函数。
使用> methods(class="data.frame")可以查看数据帧的通用函数。
使用> methods(plot)可以查看plot函数能处理的类别。

0 1
原创粉丝点击