一定要先了解缺失机制,即为什么会产生缺失值。
对于随机产生的缺失值,可以删除,删除的对象分为两类,变量的删除,以及观测值的删除。当某一变量的缺失值比例很高的时候,可以直接删除,也可以用哑变量进行标志。
但缺失值的产生不是随机的,要根据它产生原因用不同的方法填补;
主要介绍三个包的常用于填补缺失值的函数。
思路一般是要定位缺失值以及查看缺失值的数量:
is.na()
sum(is.na())
md.pattern() mice包
computemissings包
填充:na.fill()
填充,是一个比较有意思的操作,你的原始数据有可能会有缺失值NA,在做各种计算时,就会出现有问题。一种方法是,你把NA值都去掉;另外一种方法是,你把NA值进行填充后再计算。那么在填充值时,就有一些讲究了。
把NA值进行填充。
# 生成数据框
> df<-data.frame(a=c(1,NA,NA,2,NA),
+ b=c('B','A','B','B',NA),
+ c=c(rnorm(2),NA,NA,NA));df
a b c
1 1 B 0.2670988
2 NA A -0.5425200
3 NA B NA
4 2 B NA
5 NA <NA> NA
# 把数据框a列的NA,用9进行填充
> na.fill(df$a,9)
[1] 1 9 9 2 9
# 把数据框中的NA,用1进行填充
> na.fill(df,1)
a b c
[1,] " 1" "B" " 0.2670988"
[2,] "TRUE" "A" "-0.5425200"
[3,] "TRUE" "B" "TRUE"
[4,] " 2" "B" "TRUE"
[5,] "TRUE" "TRUE" "TRUE"
填充时,有时并不是用某个固定的值,而是需要基于某种规则去填充。
# 生成一个zoo类型的数据
> z <- zoo(c(2, NA, 1, 4, 5, 2), c(1, 3, 4, 6, 7, 8));z
1 3 4 6 7 8
2 NA 1 4 5 2
# 对NA进行线性插值
> na.approx(z)
1 3 4 6 7 8
2.000000 1.333333 1.000000 4.000000 5.000000 2.000000
# 对NA进行线性插值
> na.approx(z, 1:6)
1 3 4 6 7 8
2.0 1.5 1.0 4.0 5.0 2.0
# 对NA进行样条插值
> na.spline(z)
1 3 4 6 7 8
2.0000000 0.1535948 1.0000000 4.0000000 5.0000000 2.0000000
另外,我们可以针对NA的位置进行填充,比如用前值来填充或后值来填充。
> df
a b c
1 1 B 0.2670988
2 NA A -0.5425200
3 NA B NA
4 2 B NA
5 NA <NA> NA
# 用当前列中,NA的前值来填充
> na.locf(df)
a b c
1 1 B 0.2670988
2 1 A -0.5425200
3 1 B -0.5425200
4 2 B -0.5425200
5 2 B -0.5425200
# 用当前列中,NA的后值来填充
> na.locf(df,fromLast=TRUE)
a b c
1 1 B 0.2670988
2 2 A -0.5425200
3 2 B <NA>
4 2 B <NA>
以下函数参数较为简单,help查看就可以了。
compute函数 计算数据集缺少值,并确定用那种方法进行填补,method有median/mode以及random forest三个方法;
而对于random forest是不支持字符类型值得。所以只能用于数值或者因子类型。而median/mode,当变量取值为字符、因子型时一般为mode,数值型时为median。数据数据的格式一定要是data.frame
impute函数,则是将compute的训练结果运用于需要进行填补的数据集上,该数据集为data.frame,且变量名要求和compute中data的一样。
例子:
train <- data.frame(v_int=as.integer(c(3,3,2,5,1,2,4,6))
v_num=as.numeric(c(4.1,NA,12.2,11,3.4,1.6,3.3,5.5)),
v_fact=as.factor(c('one','two',NA,'two','two','one','two','two')), stringsAsFactors = FALSE))
values <- compute(train, method="randomForest")
values2 <- compute(train) i
newdata <- data.frame(v_int=as.integer(c(1,1,2,NA))
v_num=as.numeric(c(1.1,NA,2.2,NA)),
v_fact=as.factor(c('one','one','one',NA)), stringsAsFactors = FALSE))
is.na(newdata)
colSums(is.na(newdata))
impute(newdata,object=values)
impute(newdata,object=values2)