NA存在的情况下,向量或因子间的比较

问题

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

方案

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

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

通常情况下,当你比较两个包含NA值的向量或因子时,原始值是NA,结果也将有NA。根据你的目的,这(不)可能为你所需。

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

可以与NA相比的一个函数

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

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

使用该函数的例子

比较两个布尔向量:

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

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

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

原文链接:http://www.cookbook-r.com/Manipulating_data/Comparing_vectors_or_factors_with_NA/