高级编程--创建函数(函数语法、对象范围、环境)
高级编程--创建函数
在R中处处是函数。算数运算符+、-、/和*实际上也是函数。例如,2 + 2等价于 "+"(2, 2)。
1. 函数语法
函数的语法格式是:
functionname <- function(parameters){ statements return(value) }
如果函数中有多个参数,那么参数之间用逗号隔开。
参数可以通过关键字和/或位置来传递。另外,参数可以有默认值。请看下面的函数:
f <- function(x, y, z=1){ result <- x + (2*y) + (3*z) return(result) }
f(2,3,4) #通过位置传递
f(2,3) #通过位置传递
f(x=2, y=3) #通过关键字传递
f(z=4, y=2, 3) #y和z是通过关键字传递的
可以使用args()函数来观测参数的名字和默认值:
args(f)
args()被设计用于交互式观测。如果你需要以编程方式获取参数名称和默认值,可以使用formals()函数。它返回含有必要信息的列表。
参数是按值传递的,而不是按地址传递。请看下面这个函数语句:
result <- lm(height ~ weight, data=women) result
2. 对象范围
在典型情况下,有如下几点:
(1)在函数之外创建的对象是全局的(也适用于函数内部)。在函数之内创建的对象是局部的(仅仅适用于函数内部)。
(2)局部对象在函数执行后被丢弃。只有那些通过return()函数(或使用算子<<-分配)传回的对象在函数执行之后可以继续使用。
(3)全局对象在函数之内可被访问(可读)但是不会改变(除非使用<<-算子)。
(4)对象可以通过参数传递到函数中,但是不会被函数改变。传递的是对象的副本而不是变量本身。
x <- 2 y <- 3 z <- 4 f <- function(w){ z <- 2 x <- w*y*z return(x) } f(x)
x
结果分析:在这个例子中,x的一个副本被传递到函数f()中,但是初始的x不变。y的值通过环境得到。尽管z存在于环境中,但是在函数中设置的值被使用并不改变在环境中的值。
3 环境
在R中,环境包括框架和外壳。框架是符号-值(对象名称及其内容)的集合,外壳是指向封闭环境的一个指针。封闭环境也称为父环境。R允许人们在语言内部操作环境,以便达到对范围的细微控制以及函数和数据的分离。
在互动部分,当你第一次看到R的提示时,你处于全局环境。你可以通过new.env()函数创建一个新的环境并通过assign()函数在环境中创建任务。对象的值可以通过get()函数从环境 中得到。这里有一个例子:
x <- 5 myenv <- new.env() assign("x", "Homer", env=myenv) ls()
ls(myenv)
x
get("x", env=myenv)
结果分析:在全局环境中存在一个称为x的对象,其值为5。一个称为x的对象还存在于myenv的环境中,其为"Homer"。
另外使用assign()和get()函数时可以使用$符号。例如:
myenv <- new.env() myenv$x <- "Homer" myenv$x
parent.env()函数展示了父环境。继续这个例子,myenv的父环境就是全局环境:
parent.env(myenv)
全局环境的父环境是空环境。
因为函数是对象,所以它们也有环境。这在探讨函数闭包(function closure,以创建时状态被打包的函数)时非常重要 。请看由另一个函数创建的函数:
trim <- function(p){ trimit <- function(x){ n <- length(x) lo <- floor(n*p) + 1 hi <- n + 1 - lo x <- sort.int(x, partial = unique(c(lo, hi)))[lo:hi] } trimit }
trim(p)函数返回一个函数,即从矢量中修剪掉高低值的p%:
x <- 1:10 trim10pct <- trim(.1) y <- trim10pct(x) y
trim20pct <- trim(.2) y <- trim20pct(x) y
这样做是因为p值在trimit()函数的环境中并被保存在函数中:
ls(environment(trim10pct))
get("p", env=environment(trim10pct))
一般情况下,对象的值是从本地环境中获得的。如果未在局部环境中找到对象,R会在父环境中搜索,然后是父环境的父环境,直到对象被发现。如果R搜索到空环境仍未搜索到对象,它会抛出一个错误。我们把它称为词法域(lexical scoping)。
本文来自博客园,作者:zhang-X,转载请注明原文链接:https://www.cnblogs.com/YY-zhang/p/15154237.html