r - R 的 apply 系列不仅仅是语法糖吗?

标签 r apply

...关于执行时间和/或内存。

如果这不是真的,请用代码片段证明这一点。请注意,矢量化带来的加速不算在内。加速必须来自 apply (tapply, sapply, ...) 本身。

最佳答案

apply R 中的函数并未提供比其他循环函数更高的性能(例如 for )。一个异常(exception)是 lapply它可能会快一点,因为它在 C 代码中比在 R 中完成更多的工作(请参阅 this question for an example of this )。

但一般来说,规则是为了清晰起见,您应该使用 apply 函数,而不是为了性能

我想补充一点,应用函数有 no side effects ,这是使用 R 进行函数式编程时的一个重要区别。这可以通过使用 assign 来覆盖。或<<- ,但这可能非常危险。副作用还会使程序更难理解,因为变量的状态取决于历史记录。

编辑:

只是为了强调这一点,用一个递归计算斐波那契数列的简单例子;这可以运行多次以获得准确的测量结果,但关键是这些方法都没有显着不同的性能:

fibo <- function(n) {
  if ( n < 2 ) n
  else fibo(n-1) + fibo(n-2)
}
system.time(for(i in 0:26) fibo(i))
# user  system elapsed 
# 7.48    0.00    7.52 
system.time(sapply(0:26, fibo))
# user  system elapsed 
# 7.50    0.00    7.54 
system.time(lapply(0:26, fibo))
# user  system elapsed 
# 7.48    0.04    7.54 
library(plyr)
system.time(ldply(0:26, fibo))
# user  system elapsed 
# 7.52    0.00    7.58 

编辑 2:

关于 R 并行包的使用(例如 rpvm、rmpi、snow),这些通常会提供 apply系列函数(即使是 foreach 包本质上是等效的,尽管有名称)。这是 sapply 的一个简单示例函数位于 snow :

library(snow)
cl <- makeSOCKcluster(c("localhost","localhost"))
parSapply(cl, 1:20, get("+"), 3)

本例使用socket集群,不需要安装额外的软件;否则您将需要 PVM 或 MPI 之类的东西(请参阅 Tierney's clustering page )。 snow具有以下应用功能:

parLapply(cl, x, fun, ...)
parSapply(cl, X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE)
parApply(cl, X, MARGIN, FUN, ...)
parRapply(cl, x, fun, ...)
parCapply(cl, x, fun, ...)

这是有道理的 apply函数应该用于并行执行,因为它们没有 side effects 。当您更改 for 内的变量值时循环,它是全局设置的。另一方面,所有apply函数可以安全地并行使用,因为更改是函数调用的本地更改(除非您尝试使用 assign<<- ,在这种情况下可能会引入副作用)。不用说,小心局部变量和全局变量至关重要,尤其是在处理并行执行时。

编辑:

这是一个简单的示例,用于演示 for 之间的差异和*apply就副作用而言:

df <- 1:10
# *apply example
lapply(2:3, function(i) df <- df * i)
df
# [1]  1  2  3  4  5  6  7  8  9 10
# for loop example
for(i in 2:3) df <- df * i
df
# [1]  6 12 18 24 30 36 42 48 54 60

注意df是如何父环境中的内容被 for 更改但不是*apply .

关于r - R 的 apply 系列不仅仅是语法糖吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2275896/

相关文章:

R:水平图上的叠加图

r - 如何使用 ggplot 在同一图中绘制两个平滑样条线?

R:使用特定的构造函数创建新的类后代到 "data.frame"

如果列值不为 NULL,则 Python pandas 应用函数

python - 如何在 Pandas 中按对象分组应用滚动功能

r - glm.nb 与 sqrt 链接

r - ggplot2 示例中的两点运算符

r - 计算 cummean() 和 cumsd(),同时忽略 NA 值并填充 NA

python - Pandas 通过计算多列将函数应用于每一行

r - 对各种迭代应用贝叶斯模型 (JAGS)