【问题标题】:Validation function testing a value only if of a given character length验证函数仅在具有给定字符长度时测试值
【发布时间】:2023-02-07 20:30:57
【问题描述】:

我正在编写一个函数来验证某些代码。

代码是应满足两个条件的整数:

  1. 属于n长度(为了这个例子,我们假设 2)
  2. 更复杂的检查(与这个简化的示例无关,但关键方面是这将需要多行代码和单独的分配)

    为了避免无用的计算,我只希望函数在满足第一个条件时评估条件 2。

    codes <- c(16, 19, 12, 8)
    
    is_valid <- function(code) {
        if (nchar(code) != 2) {
            return(FALSE)
        } else {
            # This part is not relevant
            val1 <- as.integer(substr(code, 1, 1))
            val2 <- as.integer(substr(code, 2, 2))
            sum <- val1 + val2
            validator <- 10 - sum %% 3
            return(validator == 0)       
        } 
    }
    

    问题:如果我传递单个元素(例如is_valid(16),这很有效,但是如果我尝试传递向量is_valid(codes),我会收到此错误:

    Error in if (nchar(code) != 2) { : the condition has length &gt; 1

    我知道这是因为 if 没有向量化。我尝试用 ifelse() 替换它,但在这种情况下它实际上不起作用,因为第二个标准是一段多行代码。

    我觉得有一个简单的编程解决方案。

【问题讨论】:

  • 我会重新编写您的函数以期待矢量化输入,或者查看基本函数Vectorize()
  • 此外,ifelse() 不适合您的用例的另一个原因是 ifelse() 经常计算所有可能的输出 - 如果至少一个输入测试评估为“真”,至少一个“假”,它将计算两种结果对于输入向量的所有元素。

标签: r function vectorization


【解决方案1】:

问题出在逻辑测试if (nchar(code) != 2)。在 R 中,if 语句中的逻辑测试必须返回单个逻辑真或假。在您的情况下,它将返回一个合乎逻辑的向量:

codes <- c(16, 19, 12, 8)
nchar(codes) != 2
#> [1] FALSE FALSE FALSE  TRUE

if 语句将使用此向量的第一个元素进行流量控制(同时也会发出警告),因此您的函数将处理全部的通过 else 语句向量 codes

我的猜测是您想要矢量化输出。在这种情况下,我们可以使用ifelse,甚至可以简单地独立检查两个逻辑测试并返回由逻辑 AND 组合的结果:

is_valid <- function(code) {
    
    test1 <- nchar(code) == 2

    val1 <- as.integer(substr(code, 1, 1))
    val2 <- as.integer(substr(code, 2, 2))
    sum <- val1 + val2
    validator <- (10 - sum) %% 3
    test2 <- validator == 0 & !is.na(validator)
    
    return(test1 & test2)

}

is_valid(codes)
#> [1]  TRUE  TRUE FALSE FALSE

创建于 2023-02-07 reprex v2.0.2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-19
    • 2013-11-25
    • 2018-10-31
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    相关资源
    最近更新 更多