2013-06-17 8 views
7

Gibt es einen booleschen Operator, der mir NA gibt, wenn eines der Teile 10 ist? NA-Erkennung boolescher Operator

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

Derzeit würde ich gerne haben:

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

PS:

ich für einen Operator x bin auf der Suche nach dem

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

so konnte ich tun

result <- a x b 
+1

Es wäre hilfreich, dies in tatsächliche R-Syntax zu setzen, so ist es klar, was Sie fragen. – Thomas

+2

könnten Sie 'any' versuchen ...' xx <- c (1,2,3, NA, 4,5); any (is.na (xx)) ' – Arun

+1

@Arun' any' ist eine Erweiterung von '|' und '|' funktioniert tatsächlich so, wie Hoffmann es möchte. Die Erweiterung von '&' ist 'all' und es hat das gleiche Problem – Dason

Antwort

9

Sie könnten Ihren eigenen Operator definieren, der das tut, was Sie wollen.

> `%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 
6

Dason Ansatz ist cool, aber wenn Sterbliche etwas besser lesbar wollen, verwenden Sie diese:

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

Ergebnisse:

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

EDIT: Benchmarking:

sollte es Beachten Sie, dass der Ansatz von DASON am schnellsten ist, wie unten gezeigt:

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) 

Hinweis: %&2% ist eine lustige Alternative, die ich von Glück gerade gefunden habe :-)

Lassen Sie uns all dies zusammenstellen, um zu sehen, was passiert:

`%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 

Lustig, der Compiler nicht ändert alles hier!

+0

Sicher! Mein Hauptvorschlag war nur, dass wir unseren eigenen Betreiber bauen könnten, da ich nicht glaube, dass es einen eingebauten Operator gibt, der das macht, was wir wollen. Die boolesche Algebra in meiner Antwort sollte nicht zu schlecht sein, um zu folgen, und auf jeden Fall ist es einfach genug, die Wahrheitstabelle zu erstellen (wie Sie), um zu sehen, dass es die gewünschte Antwort gibt. Schöne Alternative aber! – Dason

+0

@Dason und deine Antwort ist die schnellste, siehe oben bearbeiten! –