r语言 - 为什么在%中包含%的条件会忽略缺失的值?



我在一个条件中使用%in%时遇到了一个意外的输出,同时重新编码一个分类变量。

当左边向量的一个元素是NA时,条件的计算结果是FALSE,而我期望它是NA

期望的行为是用|

分隔两个==条件的更详细的语句。
dt <- data.frame(colour = c("red", "orange", "blue", NA))
# Expected
dt$is_warm1 <- ifelse(dt$colour == "red" | dt$colour == "orange", TRUE, FALSE)
# Unexpected
dt$is_warm2 <- ifelse(dt$colour %in% c("red", "orange"), TRUE, FALSE)
dt
#>   colour is_warm1 is_warm2
#> 1    red     TRUE     TRUE
#> 2 orange     TRUE     TRUE
#> 3   blue    FALSE    FALSE
#> 4   <NA>       NA    FALSE

这在重新编码分类变量时非常没有帮助,因为它会静默地填充缺失的值。为什么会发生这种情况,是否有任何替代方案不涉及列出所有==条件?(想象colour包含30个可能的关卡)。

a %in% b只是match(a, b, nomatch = 0) > 0的简写(检查%in%的源代码以满足您自己的情况)。

您可以通过删除nomatch = 0参数获得预期的结果:

match(dt$colour, c("red", "orange")) > 0
#> [1] TRUE TRUE   NA   NA

当然不需要ifelse

%in%检查NA是否在列表中。考虑以下两个场景

NA %in% 1:3
# [1] FALSE
NA %in% c(1:3, NA)
# [1] TRUE

这允许你检查NA是否在向量中

如果您想保留NA值,您可以编写自己的替代

`%nain%` <- function(val, list) {
ifelse(is.na(val), NA, val %in% list)
}

然后你可以使用

dt$is_warm3 <- dt$colour %nain% c("red", "orange")

这是帮助文档中的一些信息?%in%

所以你可以在最后一行看到%in%从不返回NA,所以这就是为什么它返回FALSE而不是NA。它正在检查遗漏的值,正如@MrFlick在他的回答中提到的

确切地说,什么匹配什么在某种程度上是一个定义问题。对于所有类型,NA只匹配NA,不匹配其他值。实数和复数值时,NaN值被视为匹配任何其他NaN值,但是不匹配NA,对于复数x,实部和虚部必须匹配两者(除非包含至少一个NA)。

如果任何输入是字节序列,则将字符串作为字节序列进行比较标记为"字节",如果它们在中,则被视为相等不同的编码,但在翻译为UTF-8时是一致的(参见编码)。

, % %从未在如果返回NA使它特别有用条件。

最新更新