📜  R 编程中的条件处理

📅  最后修改于: 2022-05-13 01:54:23.329000             🧑  作者: Mango

R 编程中的条件处理

决策处理或条件处理是任何编程语言中的一个重要点。大多数用例会产生正面或负面的结果。有时有可能对不止一种可能性进行条件检查,并且它存在于 n 种可能性中。在本文中,我们将讨论 R 语言中的条件处理是如何工作的。

沟通潜在问题

开发人员总是编写好的代码来获得好的结果。并非所有问题都出乎意料。很少有预期的潜在问题是,

  • 为变量提供错误类型的输入。代替数字,我们给出字母数字值,
  • 上传文件时,上述位置不存在文件,
  • 计算某个值后的结果输出应为数字,但原始输出为空或 null 或无效

在这些情况下,R 代码可能会出错。并且可以通过错误、警告和消息来传达它们。 stop()引发致命错误并强制所有执行终止。当函数无法继续时使用错误。警告由warning()生成,用于显示潜在问题,例如当矢量化输入的某些元素无效时,例如 log(-1:2)。消息由message()生成,用于以用户可以轻松抑制的方式提供信息输出。

以编程方式处理条件

在 R 语言中,有三种不同的工具可用于以编程方式处理包括错误在内的条件。 try()使您能够在发生错误时继续执行。
例子:

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


R
# Class of success
class(success)


R
# Class of failure
class(failure)


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)


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!") 
    })


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!") 
    })


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!!!


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"
)



输出:

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" 

当我们将代码放入 try 块中时,代码会执行,甚至会发生错误,并且对于正确的结果,这将是最后评估的结果,如果失败,它会给出“try-error”。 tryCatch()指定处理函数,用于控制发出条件信号时发生的情况。可以针对警告、消息和中断采取不同的操作。
例子:

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()tryCatch()的替代方法。它建立本地处理程序,而tryCatch()注册现有处理程序。这对于使用withCallingHandlers()而不是tryCatch()处理消息最有用,因为后者将停止程序。
例子:

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!") 
    })

输出:

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!") 
    })

输出:

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

自定义信号类

R 中错误处理的挑战之一是大多数函数只是使用字符串调用stop() 。例如,可以静默忽略“预期”错误(例如模型无法收敛某些输入数据集),而可以将意外错误(例如没有可用磁盘空间)传播给用户。
例子:

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!!!

输出:

Error: Unexpected error occurred 
Execution halted

但同时,如果stop(e)行被注释掉,警告和消息都会被打印出来。

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

如果警告(w)被注释掉,那么

Important message to be noted!! 

因此,通过使用自定义信号类,我们可以区分错误。我们可以在下面详细看到
例子:

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"
)

输出:

[1] "Numeric inputs only are allowed" 

但同时,当我们通过 check_log(“100”) 时,

[1] "Only positive values are allowed"