2017-08-02 20:39:39
R有两类函数: 闭包(closure)和内置(primitive)函数
function (arglist) expr return(value)
function (arglist) .Primitive(method)
addN <- function(x, n=1) return(x+n) formals(addN)
## $x ## ## ## $n ## [1] 1
body(addN)
## return(x + n)
environment(addN)
## <environment: R_GlobalEnv>
sum
## function (..., na.rm = FALSE) .Primitive("sum")
formals(sum)
## NULL
body(sum)
## NULL
environment(sum)
## NULL
f <- function(x, y) {
print(list("本闭包环境"=ls()))
print(list("上一层环境"=ls(envir=parent.frame())))
return(x+y)}
a <- 1; b <- 2
当前环境有些什么对象?
list("当前环境"=ls())
## $当前环境 ## [1] "a" "b" "f"
运行f()函数,该闭包环境里有些什么对象?
f(a, b)
## $本闭包环境 ## [1] "x" "y" ## ## $上一层环境 ## [1] "a" "b" "f"
## [1] 3
f <- function(x) x + y y <- 10
函数定义中找不到y,则到上一级环境中找
f(1)
## [1] 11
如果找到R_GlobalEnv仍找不到,则返回错误
rm(y) f(1)
Error in f(1) : object 'y' not found
“To understand computations in R, two slogans are helpful:
- Everything that exists is an object.
- Everything that happens is a function call."
— John Chambers
x <- 5 y <- 3 c(x + y, `+`(x, y))
## [1] 8 8
all.equal(x + y, `+`(x, y))
## [1] TRUE
| 算符函数 | 等价于 |
|---|---|
| `-`(5, 2) | 5 - 2 |
| `*`(5, 2) | 5 * 2 |
| `/`(5, 2) | 5 / 2 |
| `%%`(5, 2) | 5 %% 2 |
| `==`(5, 2) | 5 == 2 |
for (i=1:2) print(i)
`for`(i, 1:2, print(i))
## [1] 1 ## [1] 2
if (3>2) print("y") else print("n")
`if`(3>2, print("y"), print("n"))
## [1] "y"
`[`(1:5, 3)
## [1] 3
`[`(iris, 4, 5)
## [1] setosa ## Levels: setosa versicolor virginica
`[[`(as.list(1:4), 2)
## [1] 2
`{`(print("a"), print(3))
## [1] "a" ## [1] 3
`<-`(x, 4); x
## [1] 4
排列组合
`%A%` <- function(n, m) choose(n, m) * factorial(m) `%C%` <- function(n, m) choose(n, m)
5 %A% 3
## [1] 60
5 %C% 3
## [1] 10
f <- function(first, second, third=5)
c(first=first, second=second,
third=third)
f("a", TRUE)
## first second third ## "a" "TRUE" "5"
f(second="a", TRUE)
## first second third ## "TRUE" "a" "5"
f(t="a", TRUE, f=5)
## first second third ## "5" "TRUE" "a"
函数作者
函数使用者
f <- function(x, y) {
if (missing(x)) x <- 0
if (missing(y)) y <- 0
return(c(x, y))
}
f()
## [1] 0 0
等价于
f <- function(x=0, y=0) c(x, y)
f <- function(x=1:4) {
stopifnot(x %in% 1:4)
paste("out:", x[[1]])
}
f()
## [1] "out: 1"
f(6)
Error: x %in% 1:4 is not TRUE
f <- function(x=c("a", "b")) {
x <- match.arg(x)
paste("out:", x)
}
f()
## [1] "out: a"
f('c')
Error in match.arg(x) :
'arg' should be one of “a”, “b” ...匹配所有的“其他”参数,可轻松地传递给其他函数
list(...)捕获所有未匹配参数...过于灵活,可导致参数跳过校验而不报错f <- function(..., na.rm=TRUE) {
# 解析...参数
args <- unlist(list(...))
# 校验: 如不是全为数值,则报错
stopifnot(all(is.numeric(args)))
# 计算均值
mean(unlist(args), na.rm=na.rm)
}
f(1, 4, 6, 9, NA)
## [1] 5
f(1, 4, 6, 9, "m")
Error: all(is.numeric(args)) is not TRUE
f <- function(...){
args <- list(...)
if ("x" %in% names(args))
print(mean(args$x))
if ("y" %in% names(args))
print(sd(args$y))
plot(...)
}
f(x=1:5, y=log(1:5), col="blue", type="b")
## [1] 3 ## [1] 0.6355094

fun<-,具体用法为fun() <-library(pryr) x <- 1:10 address(x)
## [1] "0x3831270"
`revise<-` <- function(x, n, value) {
x[[n]] <- value
x
}revise(x, 5) <- 7 x
## [1] 1 2 3 4 7 6 7 8 9 10
address(x)
## [1] "0x36a4490"
x[5] <- 7 (内置函数[<-)return()函数显式定义的值,并跳出调用栈return,则返回函数最后一个求解出的值f <- function(x, y){
if (x < y) {
"lower"
}else{
"higher or equal"
}
}
f(4, 3)
## [1] "higher or equal"
f <- function(x, y){
if (!all(is.numeric(x),
is.numeric(y)))
return(
"Must be both numeric!")
if (x < y) {
"lower"
}else{
"higher or equal"
}
}
f("a", 3)
## [1] "Must be both numeric!"
on.exit()函数可触发钩子f <- function(x){
setwd("C:")
x
}
f(1)
[1] 1
getwd()
[1] "C:/"
f <- function(x){
old.wd <- getwd()
on.exit(setwd(old.wd))
x
}
f(1)
[1] 1
getwd()
[1] "/R_Tutorial/B01 FP And OOP"
Thank you!