2012-08-15 43 views
20

定义一个量化的功能正如标题,我想知道如何在R.如何R中

  • 定义一个量化的功能是它只是在功能使用一个循环?
  • 此方法是否有效?
  • 什么是最佳实践?

回答

24

于R A级回路不矢量。 R循环将为矢量的每个元素调用相同的R代码,这将是低效的。矢量化函数通常指的是那些以有效的方式获取矢量并在整个矢量上运行的函数。最终,这将涉及一些for循环,但由于该循环正在以低级语言(如C)执行,因此它可以非常高效并适合特定任务。

考虑这个愚蠢的功能补充成对的两个向量

sillyplus <- function(x, y) { 
    out <- numeric(length = length(x)) 
    for(i in seq_along(x)) { 
     out[i] <- x[i] + y[i] 
    } 
    out 
} 

的元素它给出正确的结果

R> sillyplus(1:10, 1:10) 
[1] 2 4 6 8 10 12 14 16 18 20 

,并在它可以在整个向量一次操作感矢量化,但它不是矢量化在我上面描述的意义上,因为它是非常低效的。 +在R的C级被矢量化,所以我们实际上只需要1:10 + 1:10,而不是R.中的显式循环。

编写矢量化函数的常用方法是使用已经矢量化的现有R函数。如果你想从头开始,你想要做的事情不是作为R中的向量化函数存在的(奇数,但可能),那么你将需要弄脏你的手,并将函数的内容写入C,并在R中准备一个小包装器,用你想要的数据向量来调用你写的C函数。有些方法可以使用像Vectorize()这样的函数来伪造未矢量化的R函数的矢量化。

C不是这里唯一的选择,FORTRAN是一种可能性的是C++,并且由于德克Eddelbuettel &罗曼弗朗索瓦,后者要容易得多,现在与RCPP包做。

7

向量化函数将返回相同的长度的矢量作为它的一个参数。通常,人们可以通过使用诸如“+”,cosexp之类的内置函数的组合来获得这样的功能,其也被矢量化。

vecexpcos <- function(x) exp(cos(x)) 
vecexpcos((1:10)*pi) 
> vecexpcos((1:10)*pi) 
# [1] 0.3678794 2.7182818 0.3678794 2.7182818 0.3678794 2.7182818 0.3678794 2.7182818 0.3678794 2.7182818 

如果需要使用非矢量化功能一样sum,你可能需要调用mapplyVectorize,以获得所需的行为。