R编程补充
2023-02-07
addn = function(y) {
function(x){
x + y
}
}
addn不是一个加法器,而是一个生成加法器的工厂!
add1 = addn(1)
add2 = addn(2)
add1(10)
## [1] 11
add2(10)
## [1] 12
add1
## function(x){
## x + y
## }
## <environment: 0x564d7a739360>
add2
## function(x){
## x + y
## }
## <bytecode: 0x564d79b83f80>
## <environment: 0x564d7a78d220>
一个函数不在当前环境(例子中为全局环境)下,那么输出该函数就会一并显示其所属的环境。在add1的环境中,y是在addn(1)确定的
environment(add1)$y
## [1] 1
color_line = function(col){
function(...){
plot(..., type = "l", lty = 1, col = col)
}
}
red_line = color_line("red")
red_line(rnorm(30), main = "Red line plot")
red_line
## function(...){
## plot(..., type = "l", lty = 1, col = col)
## }
## <environment: 0x564d79850718>
environment(red_line)$col
## [1] "red"
add = function(x, y, z ){
x + y + z
}
product = function(x, y, z){
x * y * z
}
combine = function(f, x, y, z){
f(x, y, z)
}
combine(add, 3, 4, 5)
## [1] 12
combine(product, 3, 4, 5)
## [1] 60
iris[iris$Sepal.Length > quantile(iris$Sepal.Length, 0.8) &
iris$Sepal.Width > quantile(iris$Sepal.Width, 0.8) &
iris$Petal.Length > quantile(iris$Petal.Length, 0.8) &
iris$Petal.Width > quantile(iris$Petal.Width, 0.8), ]
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 110 7.2 3.6 6.1 2.5 virginica
## 118 7.7 3.8 6.7 2.2 virginica
## 132 7.9 3.8 6.4 2.0 virginica
subset(iris,
Sepal.Length > quantile(Sepal.Length, 0.8) &
Sepal.Width > quantile(Sepal.Width, 0.8) &
Petal.Length > quantile(Petal.Length, 0.8) &
Petal.Width > quantile(Petal.Width, 0.8))
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 110 7.2 3.6 6.1 2.5 virginica
## 118 7.7 3.8 6.7 2.2 virginica
## 132 7.9 3.8 6.4 2.0 virginica
subset()神奇之处在于它调整了参数被计算的环境,分两步完成,首先捕获表达式,然后调整表达式的计算。
捕获表达式意味着防止表达式被执行,而将表达式本身存储为变量的形式。具有这个功能的函数为quote()
call1 = quote(rnorm(5))
call1
## rnorm(5)
typeof(call1)
## [1] "language"
class(call1)
## [1] "call"
call本质上是一个语言对象,并且是一个函数调用
name1 = quote(rnorm)
typeof(name1)
## [1] "symbol"
class(name1)
## [1] "name"
name是一个符号(或名称)而不是函数调用
事实上,quote()捕捉到函数调用时会返回调用,而捕获到变量名时则返回一个符号。
as.list(call1)
## [[1]]
## rnorm
##
## [[2]]
## [1] 5
quote()捕获一个已知的表达式,而substitute()可以作用于任意的用户输入表达式。
rnorm(5)
## [1] 1.3606034 0.1027449 -2.0280026 -0.3213873 1.2951472
fun1 = function(x){
quote(x)
}
fun1(rnorm(5))
## x
quote(x)捕获的是表达式x,而不是输入表达式rnorm(5)。下面使用substitute():
fun2 = function(x){
substitute(x)
}
fun2(rnorm(5))
## rnorm(5)
substitute(x + y + x ^2, list(x = 1))
## 1 + y + 1^2
substitute(f(x + f(y)), list(f = quote(sin)))
## sin(x + sin(y))
substitute(x, list(x = quote(rnorm(5))))
## rnorm(5)
表达式的捕获 和 执行表达式
最后一次修改于 2023-02-07