首页 > 解决方案 > 如何检查向量是否是没有长度警告且没有抑制的单个 NA 值

问题描述

我有NA一个默认函数,但如果不是,则NA应该是不限于大小 1 的字符向量。我有一个检查来验证这些,但是is.na当向量是length大于 1 的字符向量时会产生标准警告。

so_function <- function(x = NA) {
  if (!(is.na(x) | is.character(x))) {
    stop("This was just an example for you SO!")
  }
}

so_function(c("A", "B"))
#> Warning in if (!(is.na(x) | is.character(x))) {: the condition has length >
#> 1 and only the first element will be used

防止我提出警告的一个选项是使用identical

so_function <- function(x = NA) {
  if (!(identical(x, NA) | is.character(x))) {
    stop("This was just an example for you SO!")
  }
}

我的问题是,这个函数通常会将加载到 R 中的 Excel 工作表数据作为输入,并且NA从中生成的值通常是NA_character_NA_integer_NA_real_,所以当我真正需要它时identical(x, NA)通常是。FALSETRUE

对于更广泛的上下文,我正在为包创建的 S3 类遇到此问题,下面的函数近似于我如何验证该类的多个属性,即出现警告的时间。因此,我试图避免将警告作为解决方案,因此很想知道解决此问题的最佳实践。

编辑

为了使用例更清晰,这是验证类的属性,我想确保该属性是单个NA值或任意长度的字符向量:

so_function(NA_character_) # should pass
so_function(NA_integer_) # should pass
so_function(c(NA, NA)) # should fail
so_function(c("A", "B")) # should pass
so_function(c(1, 2, 3)) # should fail

标签: r

解决方案


长度警告来自使用if,它需要一个长度为 1 的向量,并且is.na是向量化的。

您可以使用anyorall周围将is.na其压缩为长度为 1 的向量,但可能存在边缘情况,它无法按预期工作,因此我将使用短路评估来检查它的长度为 1 is.na

so_function <- function(x = NA) {
  if (!((length(x)==1 && is.na(x)) | is.character(x))) {
    stop("This was just an example for you SO!")
  }
}

so_function(NA_character_) # should pass

so_function(NA_integer_) # should pass

so_function(c(NA, NA)) # should fail
Error in so_function(c(NA, NA)) : This was just an example for you SO!

so_function(c("A", "B")) # should pass

so_function(c(1, 2, 3)) # should fail
Error in so_function(c(1, 2, 3)) : This was just an example for you SO!

另一种选择是改为使用NULL默认值。


推荐阅读