data.tableクエリによって返される結果セットが空(つまり行がゼロ)であるかどうかを確認するための専用関数があるかどうか疑問に思いました。利用可能な方法のどれが速いかを確認しようとしましたが、驚くべきことに、stock関数のnrow()
使用.N
はdata.tableで使用するよりも速いようです。これは、例で使用したdata.tableのサイズによるものですか、それとも一般的には正しいですか?
dt <- structure(list(Abandon.Period = c(8135L, 1961L, 18307L, 4353L, 2270L, 7905L, 2600L, 2406L, 2286L, 2464L)
, Activity.Flag = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L))
, .Names = c("Random.Number", "Random.Integer")
, row.names = c(NA, -10L), class = c("data.table", "data.frame"))
microbenchmark(
a = nrow(dt[Random.Number < 1 ,]) == 0
,
b = dt[Random.Number < 1 ,.N] == 0
, times = 1000
)
Unit: microseconds
expr min lq mean median uq max neval
a 253.261 281.4845 306.5689 292.8045 309.407 3569.189 1000
b 311.520 334.7630 354.3346 346.8375 361.931 3342.492 1000
編集:
dt <- data.table(Random.Number = rnorm(100000))
microbenchmark(
a = nrow(dt[Random.Number < 1 ,]) == 0
,
b = dt[Random.Number < 1 ,.N] == 0
, times = 1000
)
Unit: milliseconds
expr min lq mean median uq max neval
a 1.203515 1.287130 1.795557 1.331504 1.438513 85.51352 1000
b 1.021796 1.093638 1.607488 1.128352 1.191289 90.10088 1000
library(data.table)
library(microbenchmark)
n = 1e7
n_extracol = 20
dt <- data.table(Random.Number = rnorm(n))
dt[, sprintf("%02d", 1:n_extracol) := 22 ]
# test
n = nrow(dt[Random.Number < 1])
all(c(
dt[Random.Number < 1, .N],
dt[, sum(Random.Number < 1)],
length(dt[Random.Number < 1, which = TRUE]),
dt[.(v = 1), on = .(Random.Number < v), .N],
data.table(v = 1)[dt, on = .(v = Random.Number), roll=-Inf, .N, nomatch=0]
) == n) # TRUE
# benchmark
microbenchmark(times = 10,
nrow = nrow(dt[Random.Number < 1])
,
.N = dt[Random.Number < 1, .N]
,
sum = dt[, sum(Random.Number < 1)]
,
len = length(dt[Random.Number < 1, which = TRUE])
,
join = dt[.(v = 1), on = .(Random.Number < v), .N]
,
roll = data.table(v = 1)[dt, on = .(v = Random.Number), roll=-Inf, .N, nomatch=0]
)
私のコンピューターでの結果:
Unit: milliseconds
expr min lq mean median uq max neval cld
nrow 811.37666 929.83352 963.42572 985.02599 1016.31359 1046.15549 10 b
.N 73.84544 74.26404 79.61228 75.33567 75.71378 120.97063 10 a
sum 44.11742 44.37590 44.64419 44.54316 44.68093 45.53861 10 a
len 69.37396 70.19565 93.39528 70.99561 72.46614 251.16317 10 a
join 856.37441 861.35975 898.08747 871.39156 900.91571 1099.40732 10 b
roll 1469.73950 1478.51737 1513.49030 1487.32068 1499.74617 1699.44766 10 c
行を数える前に中間テーブル(すべての列を含む)を作成する必要があるため、それがnrow
より悪いことはかなり明らかです.N
。私はなぜ知らないroll
とjoin
そう悪いですが、私は彼らが後でさらなる最適化を参照してください可能性があると思います。
合計(@akrunのアイデア)を取ることはよりもさらに高速ですが.N
、私の好みのスタイルではありません。また、不等式による自動インデックス作成が実装さ.N
れた後、この方法が成功する可能性があります。とにかく、私はいつもOPのようなテストをします。
DT[query, stopifnot(.N == 0L)]
ゼロとの比較を除いて行数をまったく気にしない場合はany
、の代わりに使用できますがsum
、この例では少しだけ高速です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加