关于r:具有特定数量的缺失值的行数


The Number of Rows with a Specific Number of Missing Values

想象一个像下面的小数据集,它由三个变量组成:

1
2
3
4
5
6
7
8
9
10
11
12
13
 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:

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

或者所有三个值都缺失的行数-R将返回1:

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

此时有两个问题:

(1)如何计算缺少"恰好一个"或"恰好两个"值的行数?

(2)如果要在大型数据集中执行上述操作,如何将计算范围限制为v1,v2和v3(即,无需创建子集)?

我尝试了is.na,nrow和df的变体,但无法使它们工作。

谢谢!


我们可以在逻辑矩阵(is.na(df))上使用rowSums并检查NA的数量是否等于感兴趣的值。

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

为了简化操作,请创建一个函数来执行此操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

1
2
3
4
5
6
7
8
sum(Reduce(`+`, lapply(df, is.na))==1)
#[1] 2

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

f2(df, 1)

尝试一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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