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"