R语言 抽象

R语言 抽象

已经使用R语言一段时间的人,很可能已经习惯于将功能作为参数传递给其他函数。然而,人们不太可能从他们个人的自定义代码中返回函数。这实在是太可怕了,因为这样做可以开辟一个全新的抽象国际,可以大大降低完成特定风格的职责所需的代码数量和复杂性。在这里,我们提供一些简短的例子,说明R程序员如何利用词法闭包来封装记录和策略。

R编程中的抽象

在R中的实现

首先,一个简单的例子,假设你想要一个函数,为其参数提供 add_2() 。你可能可以这样写。

add_2 <- function(y) { 2 + y }

这正是你所期望的。

> add_2(1:10)
[1] 3 4 5 6 7 8 9 10 11 12

现在,假设你需要其他每一个特征,而不是提供7给它的参数。但这将是非常低效的:如果将来你发现你犯了一个错误,而且你确实想把这些数值相乘而不是相加,你将被迫在一些地方交换代码。在这个微不足道的例子中,这不会有很多麻烦,但对于更复杂的项目,重复代码是一个灾难的秘诀。一个更高的概念是写一个特征,它需要一个参数,x,返回每一个其他的函数,提供它的参数,y,到x。

add_x <- function(x) {
   function(y) { x + y }
}

现在,当你用一个参数命名 add_x 时,你可能会得到一个功能,而这个功能正是你需要的。

add_2 <- add_x(2)
add_7 <- add_x(7)
> add_2(1:10)
[1] 3 4 5 6 7 8 9 10 11 12
> add_7(1:10)
[1] 8 9 10 11 12 13 14 15 16 17

所以这似乎并不太令人震惊。但是如果你仔细看 add_x 的定义 你可能会注意到一些奇怪的东西:当它被提到以后的时候,返回的特征是如何实现发现x的?

事实证明,R是词义范围的,这意味着特征与它们所描述的环境有联系。在这种情况下,当你调用 add_x 时,你提供的x参数会被附加到返回特性的环境中。在不同的短语中,在这个简单的例子中,你可以认为R只是简单地改变了特征中x变量的所有实例,使其降低到你在调用 add_x 时指定的值。好吧,这可能是一个巧妙的技巧,但是,如何才能更有效地使用它?对于一个稍微复杂的例子,想想你正在做一些复杂的引导,为了提高效率,你预先分配容器向量来保存结果。如果你只有一个单一的效果向量,这很容易–你需要做的就是考虑到每当你向向量上传一个最终结果时,都要迭代一个索引计数器。

for (i in 1:nboot) {
 bootmeans[i] <- mean(sample(data, length(data), 
                             replace = TRUE))
}
> mean(data)
[1] 0.0196
> mean(bootmeans)
[1] 0.0188

但是,想想你需要跟踪几个非常规的统计数据,每一个都需要你保持跟踪一个独特的索引变量。如果你的bootstrapping ordinary有一点点复杂,这可能会很乏味,而且容易出错。通过使用闭包,你可以总结出所有这些簿记。下面是一个构造函数,它封装了一个预先分配的容器向量。

make_container <- function(n) {
   x <- numeric(n)
   i <- 1
  
   function(value = NULL) {
       if (is.null(value)) {
           return(x)
       }
       else {
           x[i] <<- value
           i <<- i + 1
       }  
   }
}

当你用一个问题调用 make_container 时,它会预先分配一个指定周期的数字向量n,并返回一个特征,允许你对该向量进行特征统计,而不必担心大约保持索引的音乐。如果你不该返回特征的参数是NULL,那么整个向量就是后面的。

bootmeans <- make_container(nboot)
  
for (i in 1:nboot)
bootmeans(mean(sample(data, length(data), 
                      replace = TRUE)))
> mean(data)
[1] 0.0196
> mean(bootmeans())
[1] 0.0207

在这里, make_container 是非常简单的,但它可以根据你的需要而变得复杂。例如,你可能想让构造函数进行一些昂贵的计算,而这些计算你可以不再在每次角色被称为时进行。实际上,这就是我在 boolean3 软件包中完成的,以减少每次新发布的优化习惯所进行的计算范围。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程