使用sapply还是Vector?

使用sapply还是Vector?,r,sapply,R,Sapply,我是R新手,我发现我应该使用向量作为参数来调用函数,还是使用sapply将向量中的变量一个接一个地赋给函数,这是不明确的 这不是一回事吗?如果是同一件事,为什么Sappy会存在?有没有时候我应该用一种或另一种方法,以及如何知道使用哪种方法 我想到这个问题是因为我在写这篇文章 sapply(1:3, function(i) dnorm(i,0,1)) 然后我意外地发现我能做到 dnorm(1:3,0,1) 如果我不是偶然发现它(为了避免在其他函数中犯同样的错误),我怎么知道呢 发现我试图以与此

我是R新手,我发现我应该使用向量作为参数来调用函数,还是使用sapply将向量中的变量一个接一个地赋给函数,这是不明确的

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

我想到这个问题是因为我在写这篇文章

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一般来说,当你有一个向量时,你应该总是使用
dnorm(1:3,0,1)
类语法,而不是
sapply
。它只是更快更优雅。唯一的例外是当您使用的函数未矢量化时(帮助页面中规定参数应为单个字符/数字,或者这是您自己知道未矢量化的函数)

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(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
并没有将vector作为输入。

基本上,
sapply
,以及类似的apply家族的兄弟姐妹,都是从多个项目对象构建向量/矩阵或列表的循环。请参阅以下主题的规范答案:。但是,有些操作是矢量化的(即循环在机器级别运行,如在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函数可以接受向量或列表以返回等长输出,包括
粘贴
长度
toupper
[
file.*
family,
as.*
family,
grep
family。但是,更复杂的多层操作需要迭代调用来返回使用
optim
找到的单个对象。其他非矢量化方法包括
read.csv
write.csv
merge
lm
glm
summary
。使用这些方法,apply族可以迭代调用它们,并将所有元素绑定到单个对象中,例如向量/矩阵或列表

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

kappa查看函数文档。
dnorm
的第一个参数是向量,因此使用
sapply
是没有意义的。另一方面,函数
optimize
不接受向量作为参数
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