当我使用"cv.ncvreg"(来自ncvreg
包)通过SCAD进行惩罚估计时,有时会发生错误并终止我的for循环:
library(spls)
library(ncvreg)
data("lymphoma")
x.m = lymphoma$x
y.v = lymphoma$y
y.v[y.v==2]=1
x.m = x.m[,sample(1:ncol(x.m),1000)]
tserr = rep(0,1000)
for(iter in 1:1000){
id<-sample(1:length(y.v),0.67*length(y.v))
trx<-x.m[id,];try<-y.v[id]
tsx<-x.m[-id,];tsy<-y.v[-id]
scad.fit = cv.ncvreg(X=trx, y=try, family="binomial", penalty="SCAD", nfolds = 3)
opt.lam = scad.fit$lambda[which.min(scad.fit$cve)]
final.fit = ncvreg(X=trx, y=try, family="binomial", penalty="SCAD", lambda=opt.lam)
p.vec = cbind(1,tsx) %*% coef(final.fit)
class.pred = (exp(p.vec) / (1+exp(p.vec))) > 0.5
tserr[iter] = mean(abs(class.pred - tsy))
}
## Error in dimnames(beta) <- list(varnames, lamNames(lambda)) :
## length of 'dimnames' [2] not equal to array extent
## In addition: There were 25 warnings (use warnings() to see them)
该软件包与其他数据集(如白血病、乳腺癌......
但是,lymphoma
有问题。 :(
cv.ncvreg()
和lymphoma
有什么问题?
我无法复制这个,但我将回答一些调试技巧,这些技巧在这里比在评论中更容易阅读:
- 在您的问题中包含
sessionInfo()
(或至少您的操作系统和您正在使用的软件包版本)的结果很有帮助 - 如果将
cat(iter,"n")
添加到循环代码中,则可以看到代码在哪个迭代中失败。 - 如果将
set.seed(101)
添加到代码顶部(在调用随机数生成器的第一个命令之前),它将产生(更多)可重现的结果 - 如果您进一步向循环代码添加
set.seed(1000+iter)
,那么当您发现代码在第 745 次迭代中失败时,您可以使用set.seed(1745)
直接进入该迭代,以便您可以更轻松地查看发生了什么 - 或者,可以使用
options(error=recover)
在发生错误时让 R 将你转储到调试环境中 - 或者,如果您不介意简单地跳过偶尔会产生错误的运行,您可以将有问题的函数包装在
try()
中,并在失败时执行适当的操作,例如final.fit <- try(<your code here>); if (inherits(final.fit,"try-error")) next