2016-01-02 138 views
2

我發現這個功能在任何給定的數據幀,以檢測缺失值的比例爲每列中的所有變量:刪除與超過30%的缺失值

propmiss <- function(dataframe) lapply(dataframe,function(x) data.frame(nmiss=sum(is.na(x)), n=length(x), propmiss=sum(is.na(x))/length(x))) 

我將其分配給一個變量是這樣的:

propmissdf <- propmiss(df) 

然後我遍歷數據幀爲NULL變量在我的數據是這樣的:

for(i in (1:length(df))){ 
    var = names(df)[i] 
    if((propmissdf[[var]][[3]]) > 0.3) { #the 3 index represents the proportion inside propmissdf 
    df[var] <- NULL 
    } 
} 

這給我一個錯誤:

Error in if ((propmissdf[[var]][[3]]) > 0.3) { :argument is of length zero 

但它的作品,莫名其妙。它除掉了幾個大於0.3的缺失值的變量,但是如果我再次運行for循環,它會消除更多的直到3或4次,直到它擺脫所有變量。這是爲什麼發生?請隨時糾正我的問題,或想出一個更好的方法來消除30%以上的變量。

回答

2

您可以使用這樣的事情:

df <- df[colSums(is.na(df))/nrow(df) < .3] 
  • colSums(is.na(df))將計算出有多少NA值有在每列。
  • 將輸出除以data.frame中的行數以獲得比例。
  • 使用< .3創建可用於子集相關列的邏輯比較。

樣本數據和例子:

set.seed(2) 
df <- data.frame(matrix(sample(c(NA, 1:4), 20, TRUE), nrow = 4)) 
df 
# X1 X2 X3 X4 X5 
# 1 NA 4 2 3 4 
# 2 3 4 2 NA 1 
# 3 2 NA 2 2 2 
# 4 NA 4 1 4 NA 

colSums(is.na(df))/nrow(df) 
# X1 X2 X3 X4 X5 
# 0.50 0.25 0.00 0.25 0.25 

df[colSums(is.na(df))/nrow(df) < .3] 
# X2 X3 X4 X5 
# 1 4 2 3 4 
# 2 4 2 NA 1 
# 3 NA 2 2 2 
# 4 4 1 4 NA 

僅供參考,這裏有一個快速的時間比較:

set.seed(1) 
df <- data.frame(matrix(sample(c(NA, 1:4), 4000, TRUE), ncol = 1000)) 

akfun <- function() { 
    i1 <-sapply(df, function(x) { 
    pr <- prop.table(table(factor(is.na(x), levels=c(TRUE, FALSE)))) 
    pr[as.logical(names(pr))]< 0.3 
    }) 
    df[i1] 
} 

amfun <- function() df[colSums(is.na(df))/nrow(df) < .3] 

identical(amfun(), akfun()) 
# [1] TRUE 

system.time(akfun()) 
# user system elapsed 
# 0.172 0.000 0.173 
system.time(amfun()) 
# user system elapsed 
# 0.000 0.000 0.001 
+0

你會怎樣在這之後0.3調零變量取? – jgozal

+0

@jgozal,你只需重新分配輸出:'df < - df [colSums(is.na(df))/ nrow(df)<.3]'。 – A5C1D2H2I1M1N2O1R2T1

2

我們可以遍歷與sapply列,得到'NA'值的counttable,使用`prop.table來查找比例並創建一個邏輯向量。

i1 <-sapply(df, function(x) { 

     pr <- prop.table(table(factor(is.na(x), levels=c(TRUE, FALSE)))) 

     pr[as.logical(names(pr))]< 0.3 

}) 

此矢量可用於對列進行子集。

df[i1] 

如果我們需要刪除的列

df[!i1] <- list(NULL) #contributed by @Ananda Mahto 
df 
# X2 X3 X4 X5 
#1 4 2 3 4 
#2 4 2 NA 1 
#3 NA 2 2 2 
#4 4 1 4 NA 

注:df從@Ananda Mahto的帖子

+1

嘗試使用'df < - cbind(df,df)'。見[這裏](http://stackoverflow.com/questions/19434778/behavior-of-null-on-lists-versus-data-frames-for-removing-data)。 – A5C1D2H2I1M1N2O1R2T1