找到两个变量的成对完整数据的最简单方法是什么?

What is the easiest way to find the pairwise complete data for two variables?

假设您有两个变量都有一些缺失数据,但这些缺失数据可能不会完全重叠。找到没有缺失值的公共数据点数量的最简单方法是什么?是否有一些内置功能?

一种方法是创建如下函数:

pairwise.miss = function(x, y) {
  #deal with input types
  x = as.vector(x)
  y = as.vector(y)
  #make combined object
  c = cbind(x, y)
  #remove NA rows
  c = c[complete.cases(c), ]
  #return length
  return(nrow(c))
}

另一个想法是使用一些函数 returns 成对的完整数据。例如,Hmisc 中的 rcorr() 会执行此操作,但对于非数字数据可能会出错。所以:

rcorr(x, y)$n[1,2]

有没有更简单的方法?

一种可能的解决方案是使用 is.na 和逻辑运算符:

!(is.na(x) | is.na(y))        # logical vector

which(!(is.na(x) | is.na(y))) # integer vector of indices.

如果您只需要总数,请使用:

sum(!(is.na(x) | is.na(y)))

您可以简单地列出 complete.cases()sum() 输出中的两个变量。

x <- c(1, 2, 3, NA, NA, NA, 5)
y <- c(1, NA, 3, NA, 3, 2, NA)

complete.cases(x, y)
#[1] TRUE FALSE TRUE FALSE FALSE FALSE FALSE

sum(complete.cases(x, y))
#[1] 2

逻辑向量的总和是 TRUE 个元素的数量,因为 TRUE 被强制为 1 而 FALSE 被强制为 0。

这适用于任何数据类型。但是,请注意空字符串,即 "",不被视为缺失。实际缺失的字符值由 NA_character_.

表示

我对上面给出的解决方案进行了基准测试:

if (!require("pacman")) install.packages("pacman")
pacman::p_load(microbenchmark)

#fetch some data
x = iris[1] #from isis
y = iris[1]
x[sample(1:150, 50), ] = NA #random subset
y[sample(1:150, 50), ] = NA

#benchmark
times = microbenchmark(pairwise.function = pairwise.miss(x, y),
                       sum.is.na = sum(!is.na(x) & !is.na(y)),
                       sum.is.na2 = sum(!(is.na(x) | is.na(y))),
                       sum.complete.cases = sum(complete.cases(x, y)));times

结果:

> times
Unit: microseconds
               expr     min       lq      mean   median       uq     max neval
  pairwise.function 202.205 217.2935 244.31481 233.3150 253.8460 450.763   100
          sum.is.na  75.594  78.5500  89.26383  80.5730  94.1035 248.558   100
         sum.is.na2  74.662  77.6170  89.23899  80.5725  94.8825 167.676   100
 sum.complete.cases  14.311  16.1770  18.77197  17.1105  17.7330 155.233   100

所以与 sum.complete.cases 相比,我原来的方法非常慢。

也许这种计算很少需要速度,但是在同样容易使用的情况下,不妨使用最有效的方法。