R語言中缺失值NA的處理
一般在專案中,資料可能會因為裝置故障、未作答問題或誤編碼資料的原因不完整。在R中NA(not available,不可用)表示缺失值。
函式is.na()允許你檢測缺失值是否存在。該函式作用於檢測物件之後將返回一個相同大小的物件,其中缺失值的位置被改寫為true,其他不是缺失值的位置則為false。
> which(is.na(nhanes2)) #返回缺失值的位置
> sum(is.na(nhanes2)) #計算資料集nhanes2中的缺失值總數
> sum(complete.cases(nhanes2)) #統計資料集中完整樣本的個數
可以通過md.pattern()獲取缺失值的分佈情況(mice包),其中1表示沒有缺失資料,0表示存在缺失資料:
第一行第一列的13表示有13個樣本資料是完整的,倒數第二行7表示有7個樣本少了hyp、bmi、chl三個變數,最後一行表示各個變數缺失的樣本數合計。
1.剔除缺失部分
確定缺失值以後要在分析資料前刪除這些缺失值。因為含有缺失值的算術表示式和函式的計算結果也是缺失值。
一些函式計算時擁有na.rm=TRUE,可以在計算以前移除缺失值並使用剩餘值進行計算;可以通過函式complete.cases()檢查變數中至少含有一個缺失資料的觀測值的個數。函式compete.cases()產生一個布林值向量,該向量的元素個數與資料框中的行數相同,如果資料框的響應行中不含NA值,函式返回值就是TRUE。
函式na.omit()移除所有含有缺失值的觀測,na.omit()可以刪除所有含有缺失資料的行。但踢出所有包含缺失值記錄的方法是很極端的,這樣處理缺失值太多的樣本則樣本資料幾乎沒有意義。
manyNAs(algae,0.2)可以找出資料集algae中缺失值個數大於列數20%的行,第二個引數中可以設定一個精確的列數作為界限。
2.用最高頻率來填補缺失值
填補含有缺失值記錄的另一個方法是嘗試找到這些缺失值最可能的值。對於變數分佈近似正態分佈時可以選用平均值;偏態分佈一般採用中位數代表資料中心趨勢的指標。
樣本algae第48行變數mxPH有缺失值,該變數分佈近似正態分佈,採用平均值填補缺失值:
> algae[48,"mxPH"] <- mean(algae$mxPH,na.rm = T)
其中mean()計算數值向量的平均數。
對變數Chla使用中位數填補該列中的所有缺失值而不是像上面一樣一行一行的逐個填補:
> algae[is.na(algae$Chla),"Chla"] <- median(algae$Chla,na.rm = T)
函式centralImputation()可以用資料的中心趨勢值來填補資料集的所有缺失值:
> algae <- centralImputation(algae)
數值變數用中位數,名義變數採用眾數。這種方法簡單快速,適用於大資料集,但可能導致較大的資料偏差。
3.通過變數的相關關係填補缺失值
通過探尋變數值之間的相關關係獲取缺失值較少偏差估計值。函式cor()的功能是產生變數之間的相關值矩陣,以下可以得到變數間的相關值:
> cor(algae[,4:18],use = "complete.obs")
引數use = "complete.obs"可以忽略含有NA的記錄,另外函式symnum()可以輸出用符號表示相關值的形式。測試資料集中,相關值大於0.9的兩個變數可以通過相關性填補這兩個變數的缺失值。以P04和oP04為例,需要先找到這兩個變數之間的線性相關關係:
> lm(PO4~oPO4,data = algae)
函式lm()可以用來獲取線性模型。得到PO4=42.897+1.293*oPO4
可以使用上述線性關係計算變數的缺失值,填補樣本28在變數PO4上的缺失值:
> algae[28,"PO4"] <- 42.897+1.293*algae[28,"oPO4"]
可以建構函式對所有缺失值應用這個函式:
4. 通過探索案例之間的相似性來填補缺失值
嘗試使用行(觀察值)之間的相似性來填補缺失值。相似性經常由描述觀測值的多元度量空間的變數所定義,其中歐氏距離可以非正式地定義為任何兩個案例的觀測值之差的平方和。可以使用這種度量尋找與任何含有缺失值得案例最相似的10個水樣並用他們來填補缺失值。
應用函式 knnImputation(),用中位數來填補缺失值:
> algae<- knnImputation(algae,k=10,meth = "median")
其中引數meth可選。通過個案之間的相似性填補缺失值也存在其他問題:可能存在不相關的變數扭曲相似性,甚至造成大型資料集的計算特別複雜等問題。
5.用相似樣本的缺失值替代缺失值
> donate <- nhanes2[which(apply(is.na(nhanes2),1,sum)==0),]
#無缺失值的樣本
> accept <-nhanes2[which(apply(is.na(nhanes2),1,sum)!=0),]
#存在缺失值的樣本
> sa <- donate[which(donate[,1]==accept[2,1]&donate[,3]==accept[2,3]&donate[,4]==accept[2,4]),]
對accept中的第二個樣本accept[2, ]做缺失值處理,尋找與其相似的樣本後,用找到的樣本的對應值替代缺失值:
> sa<-donate[which(donate[,1]==accept[2,1]&donate[,3]==accept[2,3]&donate[,4]==accept[2,4]),]
實際操作時若資料量過大,可以按照某些變數將資料分層,在層中對缺失值使用均值插補,即採用冷平臺插補方式。