捕捉功能的打印

时间:2016-04-05 14:35:01

标签: r lambda

我在特定功能fda中使用包fRegress。此函数包含另一个名为eigchk的函数,用于检查系数矩阵是否为单数。

这是包装所有者(J. O. Ramsay,Giles Hooker和Spencer Graves)写的功能。

eigchk <- function(Cmat) {

  #  check Cmat for singularity

  eigval <- eigen(Cmat)$values
  ncoef  <- length(eigval)
  if (eigval[ncoef] < 0) {
      neig <- min(length(eigval),10)
      cat("\nSmallest eigenvalues:\n")
      print(eigval[(ncoef-neig+1):ncoef])
      cat("\nLargest  eigenvalues:\n")
      print(eigval[1:neig])
      stop("Negative eigenvalue of coefficient matrix.")
  }
  if (eigval[ncoef] == 0) stop("Zero eigenvalue of coefficient matrix.")
  logcondition <- log10(eigval[1]) - log10(eigval[ncoef])
  if (logcondition > 12) {
      warning("Near singularity in coefficient matrix.")
      cat(paste("\nLog10 Eigenvalues range from\n",
                log10(eigval[ncoef])," to ",log10(eigval[1]),"\n"))
  }
}

正如你可以看到的那样,如果条件检查logcondition是否大于12,则打印出特征值的范围。

以下代码实现了粗糙度正则化的使用。该代码取自本书&#34;使用R和Matlab进行功能数据分析&#34;。

annualprec = log10(apply(daily$precav,2,sum))
tempbasis =create.fourier.basis(c(0,365),65)
tempSmooth=smooth.basis(day.5,daily$tempav,tempbasis)
tempfd =tempSmooth$fd

templist = vector("list",2)
templist[[1]] = rep(1,35)
templist[[2]] = tempfd

conbasis = create.constant.basis(c(0,365))
betalist = vector("list",2)
betalist[[1]] = conbasis


SSE = sum((annualprec - mean(annualprec))^2)
Lcoef = c(0,(2*pi/365)^2,0)
harmaccelLfd = vec2Lfd(Lcoef, c(0,365))
betabasis = create.fourier.basis(c(0, 365), 35)
lambda = 10^12.5
betafdPar = fdPar(betabasis, harmaccelLfd, lambda)
betalist[[2]] = betafdPar

annPrecTemp = fRegress(annualprec, templist, betalist)
betaestlist2 = annPrecTemp$betaestlist
annualprechat2 = annPrecTemp$yhatfdobj

SSE1.2 = sum((annualprec-annualprechat2)^2)
RSQ2 = (SSE - SSE1.2)/SSE
Fratio2 = ((SSE-SSE1.2)/3.7)/(SSE1/30.3)

resid   = annualprec - annualprechat2
SigmaE. = sum(resid^2)/(35-annPrecTemp$df)
SigmaE  = SigmaE.*diag(rep(1,35))
y2cMap  = tempSmooth$y2cMap

stderrList = fRegress.stderr(annPrecTemp, y2cMap, SigmaE)

betafdPar = betaestlist2[[2]]
betafd    = betafdPar$fd
betastderrList = stderrList$betastderrlist
betastderrfd   = betastderrList[[2]]

作为惩罚因素,作者使用某些lambda。 以下代码实现了对相应`lambda。

的搜索
loglam = seq(5,15,0.5)
nlam = length(loglam)
SSE.CV = matrix(0,nlam,1)
for (ilam in 1:nlam) {
    lambda = 10ˆloglam[ilam]
    betalisti = betalist
    betafdPar2 = betalisti[[2]]
    betafdPar2$lambda = lambda
    betalisti[[2]] = betafdPar2
    fRegi = fRegress.CV(annualprec, templist,
                betalisti)
    SSE.CV[ilam] = fRegi$SSE.CV
}

通过更改loglam和交叉验证的值,我认为等于最佳lambda,但如果loglam的长度为大或其值导致系数矩阵要善意。我收到以下消息:

Log10 Eigenvalues range from
-5.44495317739048  to  6.78194912518214

由上面已经提到的函数eigchk创建。 现在我的问题是,有没有办法赶上这个所谓的警告?通过catch我的意思是一些功能或方法在发生这种情况时发出警告我可以调整loglam的值。由于在此消息打印旁边的函数中没有实际的警告定义,我的想法已经用尽了。

非常感谢你的建议。

1 个答案:

答案 0 :(得分:0)

通过&#34;抓住警告&#34;,如果您的意思是,会提醒您loglam存在潜在问题,那么您可能需要查看try和{{ 1}}功能。然后,如果满足任何警告条件,您可以定义要实现的行为。

如果您只想存储警告的输出(可能从问题标题中假设,但可能不是您想要的),请尝试查看tryCatch