Open In App

Condition Handling in R Programming

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Decision handling or Condition handling is an important point in any programming language. Most of the use cases result in either positive or negative results. Sometimes there is the possibility of condition checking of more than one possibility and it lies with n number of possibilities. In this article let’s discuss how condition handling works in R language

Communicating Potential Problems 

Developers always write good code to achieve good results. Not all problems are unexpected. Few expected potential problems are,

  • Giving the wrong type of input for a variable. In the place of numbers, we are giving alphanumeric values,
  • While uploading a file, non-existence of a file in the mentioned location,
  • The resultant output after calculating some value is expected as a numeric but the original output is either empty or null or invalid

During these scenarios, there are possibilities of going wrong with R Code. And via errors, warnings, and messages they can be communicated. Fatal errors are raised by stop() and force all execution to terminate. Errors are used when there is no way for a function to continue. Warnings are generated by warning() and are used to display potential problems, such as when some elements of a vectorized input are invalid, like log(-1:2). Messages are generated by message() and are used to give informative output in a way that can easily be suppressed by the user.

Handling Conditions Programmatically 

In the R language, there are three different tools that are there for handling conditions including errors programmatically. try() gives you the ability to continue execution even when an error occurs. 
Example:

R




success <- try(100 + 200) 
failure <- try("100" + "200")


 
Output:

Error in "100" + "200" : non-numeric argument to binary operator  

R




# Class of success
class(success) 


[1] "numeric"  

R




# Class of failure
class(failure) 


[1] "try-error" 

When we put the code inside the try block, code executes, even error occurs, and also for correct results, it will be the last result evaluated, and if a failure, it will give with “try-error”. tryCatch() specifies handler functions that control what happens when a condition is signaled.  One can take different actions for warnings, messages, and interrupts. 
Example: 

R




# Using tryCatch()
display_condition <- function(inputcode)
  tryCatch(inputcode, 
           error = function(c) "Unexpected error occurred"
           warning = function(c) "warning message, but
                                  still need to look into code", 
           message = function(c) "friendly message, but
                                   take precautions") 
}
 
# Calling the function
display_condition(stop("!")) 
display_condition(warning("?!")) 
display_condition(message("?")) 
display_condition(10000)


For Input: 
display_condition(stop("!")) 
Output: 
[1] "Unexpected error occurred" 
For Input: 
display_condition(warning("?!")) 
Output: 
[1] "warning message, but still need to look into code" 
For Input: 
display_condition(message("?")) 
Output: 
[1] "friendly message, but take precautions" 
For Input: 
display_condition(10000) 
Output: 
[1] 10000 

withCallingHandlers() is an alternative to tryCatch(). It establishes local handlers, whereas tryCatch() registers existing handlers. This will be most useful to handle a message with withCallingHandlers() rather than tryCatch() since the latter will stop the program.
Example:

R




# Using tryCatch()
message_handler <- function(c) cat("Important message is caught!\n"
    tryCatch(message = message_handler,
    
        message("1st value printed?"
      message("Second value too printed!"
    })


 Output: 

Important message is caught! 

R




# Using withCallingHandlers()
message_handler <- function(c) cat("Important message is caught!\n"
withCallingHandlers(message = message_handler,
    
      message("1st value printed?"
      message("Second value too printed!"
    })


 Output: 

Important message is caught!
1st value printed?
Important message is caught!
Second value too printed!

Custom Signal Classes 

One of the challenges of error handling in R is that most functions just call stop() with a string. For example, “expected” errors (like a model failing to converge for some input datasets) can be silently ignored, while unexpected errors (like no disk space available) can be propagated to the user. 
Example:

R




# R program to illustrate
# Custom signal classes
 
condition <- function(subclass, message,
                      call = sys.call(-1), ...) {
  structure(
    class = c(subclass, "condition"),
    list(message = message, call = call),
    ...
  )
}
 
is.condition <- function(x) inherits(x, "condition")
e <- condition(c("my_error", "error"),
               "Unexpected error occurred")
stop(e) # Output as Unexpected error occurred
 
# comment out stop(e)
w <- condition(c("my_warning", "warning"),
                  "Appropriate warning!!!!")
warning(w) # Output as Appropriate warning!!!!
           # as well as Important message to be noted!!
           # will be printed
 
m <- condition(c("my_message", "message"),
               "Important message to be noted!!!")
message(m) # Output as Important message to be noted!!!


 Output: 

Error: Unexpected error occurred 
Execution halted

But at the same time, if stop(e) line is commented out, both warning and message are printed. 

Warning message: 
Appropriate warning!!!! 
Important message to be noted!! 

And if warning(w) is commented out, then 

Important message to be noted!! 

So by using custom signal classes, we can differentiate the errors. We can see that in detail below 
Example: 

R




# R program to illustrate
# Custom signal classes
 
condition <- function(subclass, message,
                      call = sys.call(-1), ...) {
  structure(
    class = c(subclass, "condition"),
    list(message = message, call = call),
    ...
  )
}
is.condition <- function(x) inherits(x, "condition")
custom_stop <- function(subclass, message,
                        call = sys.call(-1),
                        ...) {
c <- condition(c(subclass, "error"), message,
               call = call, ...)
  stop(c)
}
 
check_log <- function(x) {
  if (!is.numeric(x))
    custom_stop("invalid_class",
                "check_log() needs numeric input")
  if (any(x < 0))
    custom_stop("invalid_value",
                "check_log() needs positive inputs")
  log(x)
}
 
tryCatch(
  check_log("ant"),  # As we pass "ant", we will
                     # get Numeric inputs
                     # only are allowed as output
   
  # for input, if we give with negative value
  # let us check what happens,
  # for that uncomment below line and see,
  # obviously you get Positive
  # numeric value need to be provided
  #check_log("-100"),
  invalid_class = function(c) "Numeric inputs
                               only are allowed",
  invalid_value = function(c) "Positive numeric value
                               need to be provided"
)


 Output: 

[1] "Numeric inputs only are allowed" 

But at the same time, when we passed check_log(“100”), 

[1] "Only positive values are allowed" 


Last Updated : 30 Nov, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads