Home > front end >  Change Error Message to An Instruction for Users
Change Error Message to An Instruction for Users

Time:01-14

When I run this R code I get Error in order(res2$seed): argument 1 is not a vector as an error message in the function call at first instance but when I change the range of i to be something different like in function call at second instance, I get the expected data frame format that I want.

The Function

  abc <- function(a, z, n, ar11, p, d, q, sd = sd, j1, arr1, n_cores){
  future::plan(future::multisession)
  n_cores <- parallel::detectCores()
  cl <- parallel::makeCluster(n_cores)
  doParallel::registerDoParallel(cores = n_cores)

  message('processing...')
  `%dopar%` <- foreach::`%dopar%`
  i <- a:z
  res <- foreach::foreach(i = a:z, .packages = c('foreach', 'forecast')) %dopar% {
    set.seed(i)
    mod <- stats::arima.sim(n = n, model = list(ar = c(ar11), order = c(p, d, q)), sd = sd)
    best.mod <- forecast::auto.arima(mod, ic = "aicc")
    (cf <- best.mod$coef)
    if (length(cf) == 0) {
      rep(NA, 2)
    } else if (all(grepl(c("ar1|intercept"), names(cf))) &
               substr(cf["ar1"], 1, j1) %in% arr1) {
      c(cf, seed = i)
    } else {
      rep(NA, 2)
    }
  }
  message(' done!\n')

  res1 = res[!sapply(res, anyNA)]

  parallel::stopCluster(cl)
  options(max.print = .Machine$integer.max)

  res2 <- tibble::tibble(Reduce(function(...) merge(..., all = T), lapply(res1, function(x) as.data.frame(t(x)))))

  res2[order(res2$seed), ]

  res2 <- Reduce(function(...) merge(..., all = T), lapply(res1, function(x) as.data.frame(t(x))))
  res2[order(res2$seed), ]
}

Call Function at First Instance

abc(a = 280000,  z = 281000, n = 10, p = 1, d = 0, q = 0, ar11 = 0.8, sd = 1, j1 = 4, arr1 = "0.80")

#Error in order(res2$seed) : argument 1 is not a vector

Call Function at Second Instance

abc(a = 289800,  z = 289989, n = 10, p = 1, d = 0, q = 0, ar11 = 0.8, sd = 1, j1 = 4, arr1 = "0.80")

#ar1   seed
#1 0.8000000 289805
#2 0.8000368 289989

I want to change Error in order(res2$seed): argument 1 is not a vector when need be to instruction for this R function useers to Try another range of seeds

CodePudding user response:

You can either look before you leap by testing if the seed column exists:

abc <- function(a, z, n, ar11, p, d, q, sd = sd, j1, arr1, n_cores){

  # ...code as in OP...

  res2 <- tibble::tibble(Reduce(function(...) merge(..., all = T), lapply(res1, function(x) as.data.frame(t(x)))))

  if (!("seed" %in% colnames(res2))) {
    warning("Try another range of seeds", call. = FALSE)
  } else {
    res2[order(res2$seed), ]
  }
}

abc(a = 280000,  z = 281000, n = 10, p = 1, d = 0, q = 0, ar11 = 0.8, sd = 1, j1 = 4, arr1 = "0.80") 

# processing...
# done!
# 
# Warning message:
# Try another range of seeds 

Or ask for forgiveness instead of permission using tryCatch() and suppressWarnings() for a slightly more generic approach:

abc <- function(a, z, n, ar11, p, d, q, sd = sd, j1, arr1, n_cores){

  # ...code as in OP...

  res2 <- tibble::tibble(Reduce(function(...) merge(..., all = T), lapply(res1, function(x) as.data.frame(t(x)))))

  tryCatch(
    suppressWarnings(res2[order(res2$seed), ]),
    error = \(err) {
      if (grepl("argument 1 is not a vector", err$message)) {
        warning("Try another range of seeds", call. = FALSE)
      } else { 
        stop(err)
      }
    }
  )
}

abc(a = 280000,  z = 281000, n = 10, p = 1, d = 0, q = 0, ar11 = 0.8, sd = 1, j1 = 4, arr1 = "0.80")
# processing...
# done!
# 
# Warning message:
# Try another range of seeds 

That said, it’s better in my opinion to throw an error than a warning when a function doesn’t return the expected output. Especially if other code will depend on the result of this function. You can throw an error with your desired message by replacing warning() with stop().

  •  Tags:  
  • r
  • Related