7

NA如果任何部分是,是否有一个布尔运算符给我NA?目前

NA & FALSE == FALSE
FALSE & NA == FALSE
NA & TRUE  == NA
TRUE & NA  == NA

我想要:

NA x FALSE == NA
FALSE x NA == NA

PS:

我正在寻找一个运算符 x

  x     |  a=TRUE  |  =FALSE | =NA
-----------------------------------
b=TRUE  |    TRUE  |   FALSE |  NA
 =FALSE |    FALSE |   FALSE |  NA
 =NA    |    NA    |   NA    |  NA

所以我可以做

result <- a x b
4

2 回答 2

9

您可以定义自己的运算符来执行您想要的操作。

> `%and%` <- function(x, y){as.logical(x*y)}
> NA %and% FALSE
[1] NA
> FALSE %and% NA
[1] NA
> NA %and% TRUE
[1] NA
> TRUE %and% NA
[1] NA
于 2013-06-17T13:21:50.440 回答
6

Dason 的方法很酷,但如果想要普通人更易读的东西,请使用:

`%&%` <- function(e1, e2) ifelse(is.na(e1)|is.na(e2), NA, e1 & e2)

结果:

> x <- c(TRUE, FALSE, NA)
> outer(x, x, `%&%`)
      [,1]  [,2] [,3]
[1,]  TRUE FALSE   NA
[2,] FALSE FALSE   NA
[3,]    NA    NA   NA

编辑:基准测试:

需要注意的是,Dason的做法是最快的,如下图:

library(microbenchmark)
library(compiler)

x <- sample(c(TRUE, FALSE, NA), size=1e3, TRUE)
y <- sample(c(TRUE, FALSE, NA), size=1e3, TRUE)

`%&1%` <- function(e1, e2) ifelse(is.na(e1)|is.na(e2), NA, e1 & e2)
`%&2%` <- function(x, y) (!x | y) & (x | y) & (x | !y)
`%and%` <- function(x, y)as.logical(x*y)

注意:%&2%这是一个有趣的替代方案,我只是幸运地找到了 :-)

让我们编译所有这些来看看会发生什么:

`%C&2%` <- cmpfun(`%&2%`)
`%C&1%` <- cmpfun(`%&1%`)
`%Cand%` <- cmpfun(`%and%`)

> microbenchmark(x %&1% y, x %&2% y, x %and% y, x %C&1% y, x %C&2% y, x %Cand% y, times=1000)
Unit: microseconds
       expr     min      lq  median      uq      max neval
   x %&1% y 201.575 206.124 208.574 211.024 1822.917  1000
   x %&2% y  86.439  87.140  87.839  88.190 1244.441  1000
  x %and% y  13.299  13.999  14.349  14.700 1141.905  1000
  x %C&1% y 200.525 205.775 208.574 210.674 1554.151  1000
  x %C&2% y  84.690  85.390  86.090  86.440 1212.596  1000
 x %Cand% y  13.299  13.649  14.349  14.699 1141.555  1000

有趣的是,编译器在这里没有改变任何东西!

于 2013-06-17T13:40:05.967 回答