R語言:處理缺失值
前言
實際工作中,數據集很少是完整的,許多情況下樣本中都會包括若干缺失值NA,這在進行數據分析和挖掘時比較麻煩。
缺失值是數據中經常出現的問題,也是任何數據集中都可能出現的問題,無回答、錄入錯誤等調查中常會出現的現象都會導致缺失數據。缺失值通常會用一些特殊符號進行標記,比如9999、1990年1月1日,或者是“*”、“?”、“#”、“$”等符號。
對於缺失數據通常有三種應付手段:
(1)當缺失數據較少時直接刪除相應樣本
刪除缺失數據樣本,其前提是缺失數據的比例較少,而且缺失數據是隨機出現的,這樣刪除缺失數據后對分析結果影響不大。
(2)對缺失數據進行插補
用變量均值或中位數來代替缺失值,其優點在於不會減少樣本信息,處理簡單。但是缺點在於當缺失數據不是隨機出現時會產成偏誤。
多重插補法(Multiple imputation):多重插補是通過變量間關系來預測缺失數據,利用蒙特卡羅方法生成多個完整數據集,再對這些數據集分別進行分析,最后對這些分析結果進行匯總處理。可以用mice包實現。
(3)使用對缺失數據不敏感的分析方法,例如決策樹。
基本上缺失數據處理的流程是首先判斷其模式是否隨機,然后找出缺失的原因,最后對缺失值進行處理。
目錄
1. 缺失值與數值比較
2. 缺失值檢測
3. 函數中忽略缺失值
4. 向量中的刪除缺失值
5. na.fail和na.omit函數處理缺失值
小結:常用示例
1. 缺失值與數值比較
有時,你的數據中會包含一些缺失值,NULL, NA, 或者 NaN。它們與正常值不同,可能需要檢測缺失值是否存在。
x <- NULL
x > 5
# logical(0)
y <- NA
y > 5
# NA
z <- NaN
z > 5
# NA
2. 缺失值檢測
缺失值檢測:
is.null(x)
# TRUE
is.na(y)
# TRUE
is.nan(z)
# TRUE
注意NULL不同於其它兩個。NULL是沒有值,即空。而NA和NaN是有值的,盡管這些值是無用的。下面一個例子凸顯了它們的差別:
# Is y null?
is.null(y)
# FALSE
# Is x NA?
is.na(x)
# logical(0)
# Warning message:
# In is.na(x) : is.na() applied to non-(list or vector) of type 'NULL'
第一個例子是檢測y是否為NULL,結果是否定的。第二個例子是嘗試檢測x是否為NA,但是x沒有值能夠被檢測。
注意:無限數值用Inf(正無窮)和-Inf(負無窮)表示,相應的檢測函數為is.finite()和is.infinite()。
3. 函數中忽略缺失值
如果你對一個包含NA或NaN的向量使用諸如mean()或sum()這樣的匯總函數時,將返回NA或NaN,盡管它將會提醒你有缺失值存在,但通常是無用的。所以,需要使用na.rm這樣的函數來標記,告訴它們忽略缺失值。
vy <- c(1, 2, 3, NA, 5)
# 1 2 3 NA 5
mean(vy)
# NA
mean(vy, na.rm=TRUE)
# 2.75
vz <- c(1, 2, 3, NaN, 5)
# 1 2 3 NaN 5
sum(vz)
# NaN
sum(vz, na.rm=TRUE)
# 11
# NULL不存在問題,因為它里面根本不存在值
vx <- c(1, 2, 3, NULL, 5)
# 1 2 3 5
sum(vx)
# 11
4. 向量中的刪除缺失值
使用is.na()或is.nan()過濾來刪除向量中的缺失值。
vy
# 1 2 3 NA 5
vy[ !is.na(vy) ]
# 1 2 3 5
vz
# 1 2 3 NaN 5
vz[ !is.nan(vz) ]
# 1 2 3 5
5. na.fail()和na.omit()函數處理缺失值
R語言通過na.fail和na.omit函數可以很好地處理樣本中的缺失值。這兩個函數的說明如下所示。
函 數 | 說 明 |
na.fail | na.fail( <向量a> ) | 如果向量a內包括至少1個NA,則返回錯誤;如果不包括任何NA,則返回原有向量a |
na.omit | na.omit( <向量a> ) | 返回刪除NA后的向量a |
attr(na.omit( <向量a> ),"na.action") | 返回向量a中元素為NA的下標 |
下面來看如下相關示例:
> data <- c(1,2,NA,2,4,2,10,NA,9)
> data
[1] 1 2 NA 2 4 2 10 NA 9
> data.na.fail <- na.fail(data)
Error in na.fail.default(data) : 對象里有遺漏值
> data.na.fail
Error: object 'data.na.fail' not found
> data.na.omit <- na.omit(data)
> data.na.omit
[1] 1 2 2 4 2 10 9
attr(,"na.action")
[1] 3 8
attr(,"class")
[1] "omit"
> attr(data.na.omit,"na.action")
[1] 3 8
attr(,"class")
[1] "omit"
其中,函數na.fail和 na.omit 不僅可以應用於向量,也可以應用於矩陣和數據框。另外還可以使用!x方式方便地刪除NA。例如:
> a<-c(1,2,3,NA,NA,2,NA,5)
> a[!is.na(a)]
[1] 1 2 3 2 5
其中,is.na用於判斷向量內的元素是否為NA,返回結果應該是:向量FALSE FALSE FALSE TRUE TRUE FALSE TRUE FALSE
即a內元素為NA,其對應的下標元素是TRUE,反之是FALSE。!x是取非邏輯運算符,!is.na(a)表示a內元素不為NA,其對應的下標元素是TRUE,反之是FALSE。通過a[!is.na(a)]進行索引后,即可取出a內不為NA的元素,將其過濾。
小結:常用示例
對付缺失值有用的函數:
is.na(x)
which(is.na(x))
mean(x,na.rm=TRUE)
R中如何刪除全部是na的行和列:
> testmatrix <- matrix(nrow=6, ncol=4)
> testmatrix
[,1] [,2] [,3] [,4]
[1,] NA NA NA NA
[2,] NA NA NA NA
[3,] NA NA NA NA
[4,] NA NA NA NA
[5,] NA NA NA NA
[6,] NA NA NA NA
> testmatrix[2:5,2:3] <- seq(2)
> testmatrix
[,1] [,2] [,3] [,4]
[1,] NA NA NA NA
[2,] NA 1 1 NA
[3,] NA 2 2 NA
[4,] NA 1 1 NA
[5,] NA 2 2 NA
[6,] NA NA NA NA
> tm1<-testmatrix[,-which(apply(testmatrix,2,function(x) all(is.na(x))))]
> tm1
[,1] [,2]
[1,] NA NA
[2,] 1 1
[3,] 2 2
[4,] 1 1
[5,] 2 2
[6,] NA NA
> tm2<-tm1[-which(apply(testmatrix,1,function(x) all(is.na(x)))),]
> tm2
[,1] [,2]
[1,] 1 1
[2,] 2 2
[3,] 1 1
[4,] 2 2
R中如何如何替換na值:
#讀取數據
ts <- read.csv("ts.csv",header=TRUE)
#將缺失值替換為0
ts[is.na(ts)] <- 0
#如果希望將所有的0值再替換為100,使用語句:
ts[ts==0] <- 100
#當然也可以根據其他的判斷條件進行替換,如:
#將所有大於50的元素都替換為50
ts[ts>50] <- 50