解决方案
将for (i in 0:10) 更改为for ( i in 1:11 )。注意:当我复制并运行您的代码时,我还注意到一些不相关的括号/括号遗漏,您可能还需要修复。
说明
您的问题是R 使用基于 1 的索引系统,而不是像许多其他编程语言或某些数学公式那样基于 0 的索引系统。如果你运行下面的代码,你会得到同样的错误,它会指出问题:
k = 0:10
for ( i in 0:10 ) {
print(0:k[i])
}
Error in 0:k[i] : argument of length 0
您在第一次迭代时收到错误,因为k 中没有0 元素。将其与以下循环进行比较:
k = 0:10
for ( i in 1:11 ) {
print(0:k[i])
}
[1] 0
[1] 0 1
[1] 0 1 2
[1] 0 1 2 3
[1] 0 1 2 3 4
[1] 0 1 2 3 4 5
[1] 0 1 2 3 4 5 6
[1] 0 1 2 3 4 5 6 7
[1] 0 1 2 3 4 5 6 7 8
[1] 0 1 2 3 4 5 6 7 8 9
[1] 0 1 2 3 4 5 6 7 8 9 10
更新
您对答案的评论澄清了您需要的一些其他信息:
只是为了完全理解一切,我怎么知道在这样的情况下
这表明 R 正在索引 x 的产生和 k 的总和?
简短的回答是,这取决于您如何嵌套循环和函数调用。更详细:
- 当您调用
f() 时,您会在k 的元素上启动for 循环,因此R 正在索引for 循环内的代码块(我的re- f() 下面的格式化版本)“开启”k。对于k 中的每个元素,您将prod(...) 分配给pdf(旁注:我不知道您为什么要在此循环的每次迭代中重写pdf)
-
sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)) 产生一个长度为 max(length(w(n, k[i], gam)), length(s)) 的向量(旁注:小心回收利用!- 参见 Section 2.2 of "An Introduction to R"); prod(sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1))) 有效地索引该向量的元素
-
w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1) 产生一个长度为 max(length(w(n, k[i], gam)), length(s)) 的向量; sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)) 有效地索引该向量的元素
- 等
您通过矢量化操作显式或隐式索引的内容取决于您正在谈论的嵌套循环或函数调用的级别。您可能需要仔细考虑和计划何时要对什么进行索引,这将告诉您需要如何嵌套事物。将索引应该变化最快的操作放在最里面的调用上。例如,在效果中,prod(1:3 + sum(1:3)) 将首先对sum(1:3) 进行索引以产生总和,然后对1:3 + sum(1:3) 进行索引以产生产品。即sum(1:3) = 1 + 2 + 3 = 6,然后prod(1:3 + sum(1:3)) = (1 + 6) * (2 + 6) * (3 + 6) = 7 * 8 * 9 = 504。就像括号一样从事数学工作。
另外,另一个注意事项,我不会像在 f() 中那样在函数中引用全局变量——我在下面的代码中突出显示了你这样做的地方,并提供了一个不这样做的替代方案去做吧。
f = function(gam, del){
x = mydata # don't refer to a global variable "mydata", make it an argument
n = 10
s = n / x
k = 1:11
for (i in 1:11){
pdf = prod( sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)))
}
return(-pdf)
}
# Do this instead
# (though there are still other things to fix,
# like re-writing over "pdf" eleven times and only using the last value)
f = function(gam, del, x, n = 10) {
s = n / x
s = n / x
k = 0:10
for (i in 1:11){
pdf = prod( sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)))
}
return(-pdf)
}