2013-06-17 29 views
7

Parçalardan herhangi biri NA ise NA veren bir boole muhabiri var mı? ŞuNA tanıma boolean işleci

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

Ben istiyorum:

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

PS:

Ben

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

yüzden yapabileceği hangi bir operatör x Arıyorum

result <- a x b 
+1

Bunu gerçek R sözdizimine eklemek faydalı olacaktır, bu yüzden ne sorduğunuzu netleştirin. – Thomas

+2

, herhangi birini deneyebilirsiniz ... xx <- c (1,2,3, NA, 4,5); Herhangi bir (is.na (xx)) ' – Arun

+1

@Arun' herhangi bir '' '' '' '' bir uzantısıdır ve '' aslında Hoffmann'ın istediği şekilde çalışır. '' '' '' 'Nin uzantısı '' ve aynı sorun olan – Dason

cevap

9

İstediğiniz şeyi yapan kendi operatörünüzü tanımlayabilirsiniz.

> `%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 yaklaşımı serin olmakla birlikte, ölümlüler tarafından daha okunabilir bir şey istiyorsanız, bunu kullanın:

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

Sonuçlar:

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

DÜZENLEME: Kıyaslama:

Gelmeli Dason'un yaklaşımının en hızlı olduğu belirtilmelidir:

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) 

Not:

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

Komik, derleyici değişiklikler yapmaz: %&2% en ne olur görmek için tüm bu derlemek edelim Sadece

:-) şans buldum komik alternatiftir Burada bir şey var!

+0

Elbette! Benim ana önerim sadece kendi operatörümüzü kurabileceğimizdi, çünkü istediğimiz şeyi yapan bir inşa olduğunu düşünmüyorum. Cevabımdaki boole cebri, takip etmek için çok kötü olmamalı ve her halükarda istenen cevabı verdiklerini görmek için gerçek masayı (sizin yaptığınız gibi) inşa etmek için yeterince kolay. Yine de güzel bir alternatif! – Dason

+0

@Dason ve cevabınız en hızlı olanıdır, yukarıdaki düzenlemeyi görün! –