我有以下函数从卡方分布中提取一些数据,并使用最大似然比较X的分布与已知的卡方分布。此过程模拟nSims
次。 (我将这些结果与排列测试的结果进行比较,但不包括该代码。)
chi2c <- function(xdf=2, yObs=100, xObs=100, nSims=1000, nPerm=500, alpha=0.05){
simResults <- sapply(1:nSims, function(x){
# Draw variables
x <- rchisq(xObs, df=xdf)
# Other variables not relevant here
# [[snip]]
# Permutation test
# [[snip]]
# Calculate the statistics necessary for maximum likelihood
n <<- length(x)
sumlx <<- sum(log(x))
sumx <<- sum(x)
# Calculate the maximum likelihood estimate
dfhat <- optimize(f=c2ll, interval=c(1, 10), maximum=TRUE)$maximum
# Calculate the test statistic: -2 times the log likelihood ratio
llr <- -2 * (c2ll(2) - c2ll(dfhat))
# Compare the test statistic to its asymptotic dist: chi-squared
lReject <- llr > qchisq(1 - alpha, df=1)
# Provide the results
# [[snip]]
})
# Calcuate means across simulations
rowMeans(simResults)
}
此函数调用c2ll
,卡方似然函数
c2ll <- function(dfHat){
-n * log(gamma(dfHat/2)) - n * (dfHat/2) * log(2) +
(dfHat/2 - 1) * sumlx - sumx/2
}
此功能正是我想要的并且准确无误,但我不明白为什么我必须设置最大似然统计数据(n
,sumlx
和sumx
)在全球范围内开展工作;如果我只使用optimize
在函数内设置它们,则<-
找不到它们。我尝试在optimize
内设置它们,但这也不起作用。谢谢你的帮助。
查理
答案 0 :(得分:2)
R具有词法范围,这意味着函数在定义它们的环境中查找变量。 c2ll在全局环境中定义,因此它在函数内部看不到n,sumx和sum1x的定义。另一方面,S使用动态范围,其行为与您期望的一样(即,它在调用它的范围内查找变量)。计算机科学家普遍认为,动态范围界定是一个死路一条的坏主意,而词汇范围界定是可行的方法。
实际上,你能做些什么呢?
嗯,有几种选择......
首先,您可以在本地定义您的功能:
n <- length(x)
sumlx <- sum(log(x))
sumx <- sum(x)
c2ll <- function(dfHat){
-n * log(gamma(dfHat/2)) - n * (dfHat/2) * log(2) + (dfHat/2 - 1) * sumlx - sumx/2
}
dfhat <- optimize(f=c2ll, interval=c(1, 10), maximum=TRUE)$maximum
第二,您可以让c2ll获取其他参数,并通过优化传递这些参数。
#in global env
c2ll <- function(dfHat,n,sum1x,sumx){
-n * log(gamma(dfHat/2)) - n * (dfHat/2) * log(2) +
(dfHat/2 - 1) * sumlx - sumx/2
}
#...
#in function
n <- length(x)
sumlx <- sum(log(x))
sumx <- sum(x)
dfhat <- optimize(f=c2ll, interval=c(1, 10), n=n,sum1x=sum1x,sumx=sumx, maximum=TRUE)$maximum
两者都是干净的选项,可以保留函数的封装。
答案 1 :(得分:1)
您的simResults函数返回逻辑向量。而不是使用rowMeans,只需使用mean(simResults),结果看起来合理合理......至少在以下程度:
> chi2c(alpha=0.05)
[1] 0.057
> chi2c(alpha=0.5)
[1] 0.503
答案 2 :(得分:1)
您的问题源于R使用的词汇范围规则。请参阅language definitions手册中的更多内容。简而言之,您的函数c2ll正在查找已定义的环境中的变量。
为了避免这个问题,你必须将n,sum1x和sum2x明确地作为函数的参数传递,或者直接在ch2c函数中本地定义你的函数。
这是一个非常常见的问题,SO上有很多有趣的例子。