R中混合字符向量时NaN的is.na与is.nan检测异常问题
问题:混合字符类型向量中NaN的is.na/is.nan检测异常原因
我开发了一个可处理含NA向量的歧义消除相等运算符函数:
#' Disambiguated Equality operator between two vectors that may contain NA's #' #' Forces the equality result to be TRUE if both corresponding vector elements are either equal, or both NA. #' @param x vector of any type compatible with is.na and ==. #' @param y vector of any type compatible with is.na and ==. #' @export #' @examples #' c(NA, 1:5) %==% c(NA, 1:3,"nope", NA) #[1] TRUE TRUE TRUE TRUE FALSE FALSE gp.is.equal.force <- `%==%` <- function(x, y, vect = T) { res <- (is.na(x) & is.na(y)) | (!is.na(x) & !is.na(y) & x == y) if (!vect) res <- all(res) res }
在R 4.3.2(2023-10-31)版本中,我发现了NaN值的意外行为:
> is.na(NaN) # [1] TRUE > is.na(c(NaN, 5)) # [1] TRUE FALSE > is.na(c(NaN, NA)) # [1] TRUE TRUE > is.nan(c(NaN, NA)) # [1] TRUE FALSE > is.na(c(NaN, as.factor("abc"))) # [1] TRUE FALSE > is.nan(c(NaN, 5)) # [1] TRUE FALSE
上述结果符合预期,但当向量中加入字符类型后,检测逻辑出现异常:
> is.na(c(NA, NaN, "abc")) # [1] TRUE FALSE FALSE > is.nan(c(NA, NaN, "abc")) # [1] FALSE FALSE FALSE > is.nan(c(NaN, "abc")) #[1] FALSE FALSE
为何在混合字符类型的向量中,NaN的is.na和is.nan检测会出现不符合预期的结果?这一现象是否正常?
解答
这是R的正常行为,核心原因在于R的向量是同质类型的——一个向量里的所有元素必须属于同一数据类型,当你混合不同类型(比如数值型NaN和字符型"abc")构建向量时,R会自动执行类型强制转换,把所有元素统一转换成最宽泛的类型(这里是字符型)。
具体细节:
- 当创建
c(NA, NaN, "abc")或c(NaN, "abc")时,数值型的NaN会被强制转换成字符串"NaN",而NA则会被转换成字符型缺失值NA_character_。 is.na()检测的是缺失值标记,字符型向量中只有NA_character_会被识别为缺失值,字符串"NaN"只是普通字符,因此is.na("NaN")返回FALSE。is.nan()的作用是检测数值型的非数值(Not a Number),它仅对数值型向量有效。当向量是字符型时,所有元素都不是数值,所以is.nan()对字符型向量的任何元素都会返回FALSE,包括被转成字符串的"NaN"。
可以通过以下代码验证这一点:
vec <- c(NA, NaN, "abc") typeof(vec) # [1] "character" vec # [1] NA "NaN" "abc" is.na(vec[2]) # [1] FALSE is.nan(vec[2]) # [1] FALSE
如果需要在多类型场景下保留对NaN的识别,建议使用列表(list)存储不同类型元素,或者提前对元素类型做显式处理。
内容的提问来源于stack exchange,提问作者gaut
相关产品推荐
相关产品推荐

