2016-09-26 62 views
2

設想一個小數據集類似下面,三個變量組成:排帶有缺失值的特定數目的數目

v1 <- c(0, 1, NA, 1, NA, 0) 
v2 <- c(0, 0, NA, 1, NA, NA) 
v3 <- c(1, NA, 0, 0, NA, 0) 
df <- data.frame(v1, v2, v3) 

df 
    v1 v2 v3 
1 0 0 1 
2 1 0 NA 
3 NA NA 0 
4 1 1 0 
5 NA NA NA 
6 0 NA 0 

人們可以如下來計算的數量使用is.na命令至少有一個缺失值的行 - 和R將返回4:

sum(is.na(df$v1) | is.na(df$v2) | is.na(df$v3)) 

或行的所有三個值丟失的數量 - 和R將返回1:

sum(is.na(df$v1) & is.na(df$v2) & is.na(df$v3)) 

此時有兩個問題:

(1)如何計算缺少「正好一個」或「正好兩個」值的行數? (2)如果我要在大型數據集中執行上述操作,那麼如何將計算範圍限制爲v1,v2和v3(即不必創建子集)呢?

我試過了is.na,nrow和df的變體,但是沒能得到它們中的任何一個來工作。

謝謝!

回答

3

我們可以在邏輯矩陣(is.na(df))上使用rowSums,並檢查NAs的數量是否等於感興趣的值。

n1 <- 1 
sum(rowSums(is.na(df))==n1) 

爲了方便,創建一個函數來做到這一點

f1 <- function(dat, n){ 
      sum(rowSums(is.na(dat)) == n) 
     } 


f1(df, 0) 
#[1] 2 
f1(df, 1) 
#[1] 2 

f1(df, 3) 
#[1] 1 
f1(df, 2) 
#[1] 1 

注:rowSums是非常快的,但如果它是一個大的數據集,然後創建一個邏輯矩陣還可以在創建問題記憶。因此,在遍歷數據集的列(lapply(df, is.na))後,我們可以使用Reduce

sum(Reduce(`+`, lapply(df, is.na))==1) 
#[1] 2 

f2 <- function(dat, n){ 
     sum(Reduce(`+`, lapply(dat, is.na))==n) 
} 

f2(df, 1) 
1

試試這個:

num.rows.with.x.NA <- function(df, x, cols=names(df)) { 
    return(sum(apply(df, 1, function(y) sum(is.na(y[cols])) == x))) 
} 

df 

    v1 v2 v3 
1 0 0 1 
2 1 0 NA 
3 NA NA 0 
4 1 1 0 
5 NA NA NA 
6 0 NA 0 

num.rows.with.x.NA(df, 0, names(df)) 
#[1] 2 
num.rows.with.x.NA(df, 1, names(df)) 
#[1] 2 
num.rows.with.x.NA(df, 2, names(df)) 
#[1] 1 
num.rows.with.x.NA(df, 3, names(df)) 
#[1] 1 
+3

您在低效率的方式在這裏重新發明輪子。 R所有這些功能矢量化 –

+0

是的,如果效率是關注的@David,我們可以使用akrun的rowSums/Reduce。 –