在您的编辑之后,我相信您想要做的是查看从正态分布中提取sims
的大小样本计算出的偏度经过多少次试验,因为该水平的显着性检验过于偏斜而被拒绝。n
alph
你有几个编码问题
- 您想为每次试验进行 z 分数测试,但测试在循环之外。
- z 分数是使用向量计算的
t
,但您想使用标量计算它t[i]
。
循环内有一条return
语句将导致函数在循环的第一次迭代中终止,并返回 z 分数。由于第 2 个原因,z 分数是一个向量,但它的倒数第二个值全为零,因为您只运行了一次迭代,因此该函数的典型输出如下
0.003623371 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000
修复这些直接问题会产生以下代码
library(e1071)
testsk=function(n,alph,sims) {
t=numeric(sims)
for (i in 1:sims) {
x=rnorm(n)
t[i]=skewness(x)
zscore=t[i]/(6/n)
if(zscore>=qnorm(1-alph/2)){
print("REJECT")
}
}
}
然而,这仍然存在一些问题:
- 从编程的角度来看
- 打印出“REJECT”会立即提供反馈,但可扩展性不强。如果你有
sims=1000
你最好返回拒绝的数量,nr
. 如果您仍然想打印“拒绝”nr
时间,您可以这样做:)
- 此外,代码可以更简单,并以更多的 R 风格编写,矢量化而不是使用循环。这也将具有更快的优势。因为 R 是一种解释性语言,所以向量化会产生巨大的差异,因为数字运算可以在引擎盖下发生,而 R 不必
for
一遍又一遍地遍历你的循环。
- 也许更严重的是,存在一些统计问题:
- 6/n 是对偏度方差的估计(维基百科),但您需要标准差,因此您需要取 6/n 的平方根。
- 如果 z 分数大于第 th 分位数,代码将拒绝,但如果 z 分数小于第
1-alph/2
th 分位数,它也应该拒绝alph/2
。就目前而言,您的拒绝区域alph/2
不是alph
。
- 可能还有其他问题,但我认为这些是主要问题。(我假设您知道 6/n 只是对大样本方差的一个很好的估计。)
正确的程序如下
library(e1071)
testsk=function(n,alph,sims) {
# Generate random numbers in a matrix, each trial is a row
X=matrix(rnorm(sims*n), ncol=n)
# Get skewnesses, 1 means apply to rows
skews=apply(X,1,skewness)
# Calculate z score vector and rejection vector
zscore=skews/sqrt(6/n)
reject=!(qnorm(alph/2) < zscore & zscore < qnorm(1-alph/2))
# Return the number of rejections
sum(reject)
}
您应该能够对其进行修改以适合您的目的,但如有必要,我可以澄清一下。