优化没有在R中收敛

时间:2015-04-29 12:37:39

标签: r

我有一个函数,通过使用最大似然法估计截断高斯分布的两个矩。 在我的数据库中,我并不总能获得收敛的结果。 所以我发出警告,看看他们中有多少人。

然后我尝试使用tryCatch功能删除它们,但似乎我不知道如何正确使用它。

有人有想法这样做吗?

以下是代码:

df=as.data.frame(matrix(0,1000,2))
df$V1=runif(nrow(df),0,1)
df$V2=sample(c(1:10),nrow(df), replace=TRUE)

library(truncnorm)
f <- function(d) # d is a vector
{
tryCatch(
{
f2 <- function(x) -sum(log(dtruncnorm(d, a=0, b=1, mean = x[1], sd = x[2])))
  res <- optim(par=c(mean(d),sd(d)),fn=f2)
  if(res$convergence!=0) warning("Optimization has not converged")
  return(list(res1=res$par[1],res2=res$par[2]^2))
  },
error = function(error) {return()} 
  )
}

res1=tapply(df$V1, df$V2, function(x) f(x)$res1)

因此,我们的想法是清洁&#34; res1删除尚未收敛的值。

最好的问候。

1 个答案:

答案 0 :(得分:1)

以下是tryCatch工作原理的一个小例子。您需要在tryCatch中运行表达式并查看结果。如果表达式遇到错误(或警告),您可以调整工作流程。关键是,即使产生了警告或错误,生命也会继续,程序也不会停止。

my.list <- vector("list", 15)

set.seed(357)
for (i in 1:length(my.list)) {
  result <- tryCatch(
    {
      if (runif(1) > 0.5) {
        stop("More than 0.5")
      } else {
        42
      }
      },
    error = function(e) e
    )

  # This bit catches the result and manipulates it further (output NAs or whathaveyou)
  if (!is.numeric(result)) {
    my.list[[i]] <- "Failed to converge, coerce to NA"
  } else {
    my.list[[i]] <- result
  }
}

my.list

[[1]]
[1] 42

[[2]]
[1] 42

[[3]]
[1] 42

[[4]]
[1] 42

[[5]]
[1] "Failed to converge, coerce to NA"

[[6]]
[1] 42

[[7]]
[1] "Failed to converge, coerce to NA"

[[8]]
[1] "Failed to converge, coerce to NA"

[[9]]
[1] "Failed to converge, coerce to NA"

[[10]]
[1] "Failed to converge, coerce to NA"

[[11]]
[1] "Failed to converge, coerce to NA"

[[12]]
[1] "Failed to converge, coerce to NA"

[[13]]
[1] 42

[[14]]
[1] 42

[[15]]
[1] "Failed to converge, coerce to NA"

如果表达式未评估(遇到stop),则返回错误消息。您可以将此替换为您自己的函数,该函数使用NA输出data.frame或具有其他一些所需的行为。

# custom function that produces custom output
myFun <- function(x) {
  NA
}

set.seed(357)
for (i in 1:length(my.list)) {
  result <- tryCatch({
    if (runif(1) > 0.5) {
      stop("More than 0.5")
    } else {
      42
    }
  },
  error = myFun
  )

  my.list[[i]] <- result

}

my.list

[[1]]
[1] 42

[[2]]
[1] 42

[[3]]
[1] 42

[[4]]
[1] 42

[[5]]
[1] NA

[[6]]
[1] 42

[[7]]
[1] NA

[[8]]
[1] NA

[[9]]
[1] NA

[[10]]
[1] NA

[[11]]
[1] NA

[[12]]
[1] NA

[[13]]
[1] 42

[[14]]
[1] 42

[[15]]
[1] NA