72

NAベクトルがRに少なくとも1つあるかどうかを検出する最速の方法は何ですか? 私は使用しています:

sum( is.na( data ) ) > 0

しかし、それには、各要素、型変換、および sum 関数を調べる必要があります。

4

6 に答える 6

75

考えている:

any(is.na(data))

少し速くなるはずです。

于 2011-07-01T18:38:41.947 に答える
72

R 3.1.0 以降anyNA()は、これを行う方法です。原子ベクトルでは、これは の場合のようにベクトル全体を通過するのではなく、最初の NA の後に停止しany(is.na())ます。is.naさらに、これにより、すぐに破棄される中間論理ベクトルの作成が回避されます。Joranの例を借りる:

x <- y <- runif(1e7)
x[1e4] <- NA
y[1e7] <- NA
microbenchmark::microbenchmark(any(is.na(x)), anyNA(x), any(is.na(y)), anyNA(y), times=10)
# Unit: microseconds
#           expr        min         lq        mean      median         uq
#  any(is.na(x))  13444.674  13509.454  21191.9025  13639.3065  13917.592
#       anyNA(x)      6.840     13.187     13.5283     14.1705     14.774
#  any(is.na(y)) 165030.942 168258.159 178954.6499 169966.1440 197591.168
#       anyNA(y)   7193.784   7285.107   7694.1785   7497.9265   7865.064

ベクトルの最後の値を変更しても、大幅に高速化されていることに注意してください。これは、中間の論理ベクトルを回避するためです。

于 2016-03-01T01:45:57.003 に答える
17

これについては、いくつかのRcppプレゼンテーションで言及しており、実際にはいくつかのベンチマークがあり、R ソリューションよりも Rcpp を使用した組み込み C++の方がかなり大きな利点があることを示しています。

  • ベクトル化された R ソリューションは、ベクトル式のすべての要素を計算します。

  • あなたの目標が を満たすことだけならany()、最初の一致の後に中止することができます -- これが、私たちのRcpp シュガー(本質的には、C++ 式を R 式のように見せるための C++ テンプレート マジックです。詳細については、このビネットを参照してください) ソリューションが行うことです。 .

したがって、コンパイルされた特殊なソリューションを機能させることで、実際に高速なソリューションを得ることができます。これをこのSOの質問で提供されているソリューションと比較していませんが、パフォーマンスについてはかなり自信があります.

編集Rcpp パッケージにはディレクトリに例が含まれていますsugarPerformance。の「R-computes-full-vector-expression」よりも「sugar-can-abort-soon」が数千増加していますが、そのケースには単純なブール式がany()含まれていないことを付け加えておきます。is.na()

于 2011-07-01T20:48:52.597 に答える
8

NAで停止するforループを作成することもできますが、system.timeは、NAがどこにあるかによって異なります...(存在しない場合は、非常に時間がかかります)

set.seed(1234)
x <- sample(c(1:5, NA), 100000000, replace = TRUE)

nacount <- function(x){
  for(i in 1:length(x)){
    if(is.na(x[i])) {
      print(TRUE)
      break}
}}

system.time(
  nacount(x)
)
[1] TRUE
       User      System verstrichen 
       0.14        0.04        0.18 

system.time(
  any(is.na(x))
) 
       User      System verstrichen 
       0.28        0.08        0.37 

system.time(
  sum(is.na(x)) > 0
)
       User      System verstrichen 
       0.45        0.07        0.53 
于 2011-07-01T19:34:19.713 に答える
6

これまでに説明したさまざまな方法のいくつかについて、私の(遅い)マシンからの実際の時間は次のとおりです。

x <- runif(1e7)
x[1e4] <- NA

system.time(sum(is.na(x)) > 0)
> system.time(sum(is.na(x)) > 0)
   user  system elapsed 
  0.065   0.001   0.065 

system.time(any(is.na(x)))  
> system.time(any(is.na(x)))
   user  system elapsed 
  0.035   0.000   0.034

system.time(match(NA,x)) 
> system.time(match(NA,x))
  user  system elapsed 
 1.824   0.112   1.918

system.time(NA %in% x) 
> system.time(NA %in% x)
  user  system elapsed 
 1.828   0.115   1.925 

system.time(which(is.na(x) == TRUE))
> system.time(which(is.na(x) == TRUE))
  user  system elapsed 
 0.099   0.029   0.127

は を使用して実装されているため、match%in%が似ていることは驚くべきことではありません。%in%match

于 2011-07-01T19:55:18.747 に答える
3

あなたが試すことができます:

d <- c(1,2,3,NA,5,3)

which(is.na(d) == TRUE, arr.ind=TRUE)
于 2011-07-01T18:37:30.647 に答える