6.5 NA 存在时进行向量或因子比较

6.5.1 问题

你想在 NA 存在的情况下比较比较两个向量或因子并返回 TRUEFALSE(而不是 NA)。

6.5.2 方案

假设你有一个两列(包含布尔值)的列表:

  1. df <- data.frame(a = c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE,
  2. NA, NA, NA), b = c(TRUE, FALSE, NA, TRUE, FALSE, NA,
  3. TRUE, FALSE, NA))
  4. df
  5. #> a b
  6. #> 1 TRUE TRUE
  7. #> 2 TRUE FALSE
  8. #> 3 TRUE NA
  9. #> 4 FALSE TRUE
  10. #> 5 FALSE FALSE
  11. #> 6 FALSE NA
  12. #> 7 NA TRUE
  13. #> 8 NA FALSE
  14. #> 9 NA NA

通常情况下,当你比较两个包含NA值的向量或因子时,原始值是NA,结果也将有NA。根据你的目的,这或许是是你想要的结果。

  1. df$a == df$b
  2. #> [1] TRUE FALSE NA FALSE TRUE NA NA NA
  3. #> [9] NA
  4. # 同样的比较,但是可以生成列表的另一列:
  5. data.frame(df, isSame = (df$a == df$b))
  6. #> a b isSame
  7. #> 1 TRUE TRUE TRUE
  8. #> 2 TRUE FALSE FALSE
  9. #> 3 TRUE NA NA
  10. #> 4 FALSE TRUE FALSE
  11. #> 5 FALSE FALSE TRUE
  12. #> 6 FALSE NA NA
  13. #> 7 NA TRUE NA
  14. #> 8 NA FALSE NA
  15. #> 9 NA NA NA

6.5.2.1 可以与 NA 相比的函数

这个比较函数会把NA赋予另一个值。如果一个向量的两项都是 NA ,则返回 TRUE;如果其中一个是 NA,则返回 FALSE;所有其他比较(无NA之间)的方式是一样的。

  1. # 这个函数将会返回 TRUE,当两个元素相同(包括两个
  2. # NA),其他情况返回 FALSE
  3. compareNA <- function(v1, v2) {
  4. same <- (v1 == v2) | (is.na(v1) & is.na(v2))
  5. same[is.na(same)] <- FALSE
  6. return(same)
  7. }

6.5.2.2 使用该函数的例子

比较两个布尔向量:

  1. compareNA(df$a, df$b)
  2. #> [1] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
  3. #> [9] TRUE
  4. # 同样的比较,生成另一列
  5. data.frame(df, isSame = compareNA(df$a, df$b))
  6. #> a b isSame
  7. #> 1 TRUE TRUE TRUE
  8. #> 2 TRUE FALSE FALSE
  9. #> 3 TRUE NA FALSE
  10. #> 4 FALSE TRUE FALSE
  11. #> 5 FALSE FALSE TRUE
  12. #> 6 FALSE NA FALSE
  13. #> 7 NA TRUE FALSE
  14. #> 8 NA FALSE FALSE
  15. #> 9 NA NA TRUE

它也能用于因子,即使因子的水平处于不同的次序:

  1. # 创建一个含因子的列表
  2. df1 <- data.frame(a = factor(c("x", "x", "x", "y", "y",
  3. "y", NA, NA, NA)), b = factor(c("x", "y", NA, "x", "y",
  4. NA, "x", "y", NA)))
  5. # 比较
  6. data.frame(df1, isSame = compareNA(df1$a, df1$b))
  7. #> a b isSame
  8. #> 1 x x TRUE
  9. #> 2 x y FALSE
  10. #> 3 x <NA> FALSE
  11. #> 4 y x FALSE
  12. #> 5 y y TRUE
  13. #> 6 y <NA> FALSE
  14. #> 7 <NA> x FALSE
  15. #> 8 <NA> y FALSE
  16. #> 9 <NA> <NA> TRUE
  17. # 也能用于因子,即使因子的水平处于不同的次序
  18. df1$b <- factor(df1$b, levels = c("y", "x"))
  19. data.frame(df1, isSame = compareNA(df1$a, df1$b))
  20. #> a b isSame
  21. #> 1 x x TRUE
  22. #> 2 x y FALSE
  23. #> 3 x <NA> FALSE
  24. #> 4 y x FALSE
  25. #> 5 y y TRUE
  26. #> 6 y <NA> FALSE
  27. #> 7 <NA> x FALSE
  28. #> 8 <NA> y FALSE
  29. #> 9 <NA> <NA> TRUE