使用 sapply 还是 Vector?

Use sapply or Vector?

我是 R 的新手,我发现我是应该使用向量作为参数来调用函数还是使用 sapply 将向量中的变量一个一个地赋给函数,这让我感到模棱两可。

这不是一回事吗?如果它是同一件事,为什么 sapply 存在?有时我应该使用一种或另一种方式以及如何知道使用哪种方式?

我在写这篇文章的时候想到了这个问题

sapply(1:3, function(i) dnorm(i,0,1))

然后我无意中发现我可以做到

dnorm(1:3,0,1)

如果不是偶然发现的(为了不让其他函数重蹈覆辙)我怎么知道?

发现我试图以同样的方式更改此代码

kappa <- c(1,2,3,4,5,6,7)

sapply(kappa, function(t) 
  optimize(function(x) (t*x^22+5*x+6), c(-10,10))$minimum)

至此

kappa <- c(1,2,3,4,5,6,7)

  optimize(function(x) (kappa*x^22+5*x+6), c(-10,10))$minimum

但是没用!

拜托,我需要一个很好的解释。

谢谢

一般来说,当你有一个向量时,你应该总是使用类似 dnorm(1:3,0,1) 的语法而不是 sapply。它只是更快,更优雅。唯一的例外是当您使用的函数未矢量化时(在帮助页面中说明参数应该是单个 character/number 或者这是您自己的函数,您知道该函数未矢量化)。

sapply 适合列表:

> sapply(list(c(1:5), 5), sum)
[1] 15  5
> sum(list(c(1:5), 5))
Error in sum(list(c(1:5), 5)) : invalid 'type' (list) of argument

apply 矩阵:

> apply(matrix(1:4, 2, 2), 1, sum)
[1] 4 6
> apply(matrix(1:4, 2, 2), 2, sum)
[1] 3 7
> sum(matrix(1:4, 2, 2))
[1] 10

正如@davide 在评论中所说,optimize 不将矢量作为输入。

从根本上说,sapply 以及它在 apply 系列中的兄弟姐妹,都是构建 vector/matrix 或多项列表的循环目的。请参阅有关主题的规范答案:。然而,一些操作是矢量化的(即,循环是 运行 在机器级别,例如在 C 或 Fortran 中)并且可以接收矢量或列表并在非常快的 运行 时间内运行。

几乎总是,非循环版本 运行 更快。下面显示了更大序列输入的时序。

system.time({sapply(1:300000, function(i) dnorm(i,0,1))})
#    user  system elapsed 
#   1.097   0.026   1.169

system.time({dnorm(1:300000,0,1)})
#    user  system elapsed 
#   0.006   0.001   0.007

如您所见,dnorm 就是这样一个矢量化函数。许多 R 函数可以接受 return 等长输出的向量或列表,包括 pastelengthstoupper[file.* 系列、as.* 家庭,grep 家庭。然而,更复杂的多层操作需要迭代调用 return 单个对象,正如您在 optim 中发现的那样。其他非矢量化方法包括 read.csvwrite.csvmergelmglmsummary。使用这些方法,apply 系列可以迭代调用它们并将所有元素绑定到单个对象中,例如 vector/matrix 或 list.

kappa <- seq(1,7)

sapply(kappa, function(i) optimize(function(x) (i^x^2+5*x+6), c(-10,10))$minimum)
# [1] -9.9999263 -1.2407389 -0.9122106 -0.7784485 -0.7022782 -0.6517733 -0.6151620