4.5 缺失值

在任何规模的项目中,数据都可能由于未作答问题、设备故障或误编码数据的缘故而不完整。在R中,缺失值以符号NA(Not Available,不可用)表示。不可能出现的值(例如,被0除的结果)通过符号NaN(Not a Number,非数值)来表示。与SAS等程序不同,R中字符型和数值型数据使用的缺失值符号是相同的。

R提供了一些函数,用于识别包含缺失值的观测。函数is.na()允许你检测缺失值是否存在。假设你有一个向量:

  1. y <- c(1, 2, 3, NA)

然后使用函数:

  1. is.na(y)

将返回c(FALSE, FALSE, FALSE, TRUE)

请注意is.na()函数是如何作用于一个对象上的。它将返回一个相同大小的对象,如果某个元素是缺失值,相应的位置将被改写为TRUE,不是缺失值的位置则为FALSE。代码清单4-3将此函数应用到了我们的leadership数据集上。

代码清单4-3 使用is.na()函数

  1. > is.na(leadership[,6:10])
  2. q1 q2 q3 q4 q5
  3. [1,] FALSE FALSE FALSE FALSE FALSE
  4. [2,] FALSE FALSE FALSE FALSE FALSE
  5. [3,] FALSE FALSE FALSE FALSE FALSE
  6. [4,] FALSE FALSE FALSE TRUE TRUE
  7. [5,] FALSE FALSE FALSE FALSE FALSE

这里的leadership[,6:10]将数据框限定到第6列至第10列,接下来is.na()识别出了缺失值。

注意 缺失值被认为是不可比较的,即便是与缺失值自身的比较。这意味着无法使用比较运算符来检测缺失值是否存在。例如,逻辑测试myvar == NA的结果永远不会为TRUE。作为替代,你只能使用处理缺失值的函数(如本节中所述的那些)来识别出R数据对象中的缺失值。

4.5.1 重编码某些值为缺失值

如4.3节中演示的那样,你可以使用赋值语句将某些值重编码为缺失值。在我们的leadership示例中,缺失的年龄值被编码为99。在分析这一数据集之前,你必须让R明白本例中的99表示缺失值(否则这些样本的平均年龄将会高得离谱!)。你可以通过重编码这个变量完成这项工作:

  1. leadership$age[leadership$age == 99] <- NA

任何等于99的年龄值都将被修改为NA。请确保所有的缺失数据已在分析之前被妥善地编码为缺失值,否则分析结果将失去意义。

4.5.2 在分析中排除缺失值

确定了缺失值的位置以后,你需要在进一步分析数据之前以某种方式删除这些缺失值。原因是,含有缺失值的算术表达式和函数的计算结果也是缺失值。举例来说,考虑以下代码:

  1. x <- c(1, 2, NA, 3)
  2. y <- x[1] + x[2] + x[3] + x[4]
  3. z <- sum(x)

由于x中的第3个元素是缺失值,所以yz也都是NA(缺失值)。

好在多数的数值函数都拥有一个na.rm=TRUE选项,可以在计算之前移除缺失值并使用剩余值进行计算:

  1. x <- c(1, 2, NA, 3)
  2. y <- sum(x, na.rm=TRUE)

这里,y等于6。

在使用函数处理不完整的数据时,请务必查阅它们的帮助文档(例如,help(sum)),检查这些函数是如何处理缺失数据的。函数sum()只是我们将在第5章中讨论的众多函数之一,使用这些函数可以灵活而轻松地转换数据。

你可以通过函数na.omit()移除所有含有缺失值的观测。na.omit()可以删除所有含有缺失数据的行。在代码清单4-4中,我们将此函数应用到了leadership数据集上。

代码清单4-4 使用na.omit()删除不完整的观测

  1. > leadership # 含有缺失数据的数据框
  2. manager date country gender age q1 q2 q3 q4 q5
  3. 1 1 10/24/08 US M 32 5 4 5 5 5
  4. 2 2 10/28/08 US F 40 3 5 2 5 5
  5. 3 3 10/01/08 UK F 25 3 5 5 5 2
  6. 4 4 10/12/08 UK M 39 3 3 4 NA NA
  7. 5 5 05/01/09 UK F 99 2 2 1 2 1
  8. > newdata <- na.omit(leadership) # 仅含完整观测的数据框
  9. > newdata
  10. manager date country gender age q1 q2 q3 q4 q5
  11. 1 1 10/24/08 US M 32 5 4 5 5 5
  12. 2 2 10/28/08 US F 40 3 5 2 5 5
  13. 3 3 10/01/08 UK F 25 3 5 5 5 2
  14. 5 5 05/01/09 UK F 99 2 2 1 2 1

在结果被保存到newdata之前,所有包含缺失数据的行均已从leadership中删除。

删除所有含有缺失数据的观测(称为行删除,listwise deletion)是处理不完整数据集的若干手段之一。如果只有少数缺失值或者缺失值仅集中于一小部分观测中,行删除不失为解决缺失值问题的一种优秀方法。但如果缺失值遍布于数据之中,或者一小部分变量中包含大量的缺失数据,行删除可能会剔除相当比例的数据。我们将在第15章中探索若干更为复杂精妙的缺失值处理方法。下面,让我们谈谈日期值。