找到两个变量的成对完整数据的最简单方法是什么?
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 相比,我原来的方法非常慢。
也许这种计算很少需要速度,但是在同样容易使用的情况下,不妨使用最有效的方法。
假设您有两个变量都有一些缺失数据,但这些缺失数据可能不会完全重叠。找到没有缺失值的公共数据点数量的最简单方法是什么?是否有一些内置功能?
一种方法是创建如下函数:
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 相比,我原来的方法非常慢。
也许这种计算很少需要速度,但是在同样容易使用的情况下,不妨使用最有效的方法。