4.5 缺失值
在任何规模的项目中,数据都可能由于未作答问题、设备故障或误编码数据的缘故而不完整。在R中,缺失值以符号NA
(Not Available,不可用)表示。不可能出现的值(例如,被0除的结果)通过符号NaN
(Not a Number,非数值)来表示。与SAS等程序不同,R中字符型和数值型数据使用的缺失值符号是相同的。
R提供了一些函数,用于识别包含缺失值的观测。函数is.na()
允许你检测缺失值是否存在。假设你有一个向量:
y <- c(1, 2, 3, NA)
然后使用函数:
is.na(y)
将返回c(FALSE, FALSE, FALSE, TRUE)
。
请注意is.na()
函数是如何作用于一个对象上的。它将返回一个相同大小的对象,如果某个元素是缺失值,相应的位置将被改写为TRUE
,不是缺失值的位置则为FALSE
。代码清单4-3将此函数应用到了我们的leadership
数据集上。
代码清单4-3 使用
is.na()
函数
> is.na(leadership[,6:10])
q1 q2 q3 q4 q5
[1,] FALSE FALSE FALSE FALSE FALSE
[2,] FALSE FALSE FALSE FALSE FALSE
[3,] FALSE FALSE FALSE FALSE FALSE
[4,] FALSE FALSE FALSE TRUE TRUE
[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表示缺失值(否则这些样本的平均年龄将会高得离谱!)。你可以通过重编码这个变量完成这项工作:
leadership$age[leadership$age == 99] <- NA
任何等于99的年龄值都将被修改为NA
。请确保所有的缺失数据已在分析之前被妥善地编码为缺失值,否则分析结果将失去意义。
4.5.2 在分析中排除缺失值
确定了缺失值的位置以后,你需要在进一步分析数据之前以某种方式删除这些缺失值。原因是,含有缺失值的算术表达式和函数的计算结果也是缺失值。举例来说,考虑以下代码:
x <- c(1, 2, NA, 3)
y <- x[1] + x[2] + x[3] + x[4]
z <- sum(x)
由于x
中的第3个元素是缺失值,所以y
和z
也都是NA
(缺失值)。
好在多数的数值函数都拥有一个na.rm=TRUE
选项,可以在计算之前移除缺失值并使用剩余值进行计算:
x <- c(1, 2, NA, 3)
y <- sum(x, na.rm=TRUE)
这里,y
等于6。
在使用函数处理不完整的数据时,请务必查阅它们的帮助文档(例如,help(sum)
),检查这些函数是如何处理缺失数据的。函数sum()
只是我们将在第5章中讨论的众多函数之一,使用这些函数可以灵活而轻松地转换数据。
你可以通过函数na.omit()
移除所有含有缺失值的观测。na.omit()
可以删除所有含有缺失数据的行。在代码清单4-4中,我们将此函数应用到了leadership
数据集上。
代码清单4-4 使用
na.omit()
删除不完整的观测
> leadership # 含有缺失数据的数据框
manager date country gender age q1 q2 q3 q4 q5
1 1 10/24/08 US M 32 5 4 5 5 5
2 2 10/28/08 US F 40 3 5 2 5 5
3 3 10/01/08 UK F 25 3 5 5 5 2
4 4 10/12/08 UK M 39 3 3 4 NA NA
5 5 05/01/09 UK F 99 2 2 1 2 1
> newdata <- na.omit(leadership) # 仅含完整观测的数据框
> newdata
manager date country gender age q1 q2 q3 q4 q5
1 1 10/24/08 US M 32 5 4 5 5 5
2 2 10/28/08 US F 40 3 5 2 5 5
3 3 10/01/08 UK F 25 3 5 5 5 2
5 5 05/01/09 UK F 99 2 2 1 2 1
在结果被保存到newdata
之前,所有包含缺失数据的行均已从leadership
中删除。
删除所有含有缺失数据的观测(称为行删除,listwise deletion)是处理不完整数据集的若干手段之一。如果只有少数缺失值或者缺失值仅集中于一小部分观测中,行删除不失为解决缺失值问题的一种优秀方法。但如果缺失值遍布于数据之中,或者一小部分变量中包含大量的缺失数据,行删除可能会剔除相当比例的数据。我们将在第15章中探索若干更为复杂精妙的缺失值处理方法。下面,让我们谈谈日期值。