サンプルデータフレーム:
ngroups <- 100
nsamples <- 1000
foo <- data.frame(engine = rep(seq(1, ngroups), each = nsamples), cycles = runif(ngroups*nsamples, 0, nsamples))
各グループののを見つけて、max
で新しい変数を作成したいと思います。最大サイクルの列を各行のコマンド内で再計算するのではなく、事前に計算すると、コードが高速になると思いました。私が間違っていることが判明しました:cycles
engine
tte = max(cycles) - cycles
mutate
mutate
library(microbenchmark)
library(dplyr)
library(magrittr)
add_tte <- function(dataset){
dataset %<>% group_by(engine) %>% mutate(max_cycles = max(cycles)) %>%
mutate(tte = max_cycles - cycles) %>% select(-max_cycles) %>% ungroup
}
add_tte_old <- function(dataset){
dataset %<>% group_by(engine) %>% mutate(tte = max(cycles) - cycles) %>% ungroup
}
microbenchmark(add_tte(foo), add_tte_old(foo), times = 500)
# Unit: milliseconds
# expr min lq mean median uq max neval
# add_tte(foo) 17.45324 21.107264 26.50535 24.52625 28.75208 113.98433 500
# add_tte_old(foo) 8.10376 9.949188 13.35830 12.18336 14.52474 77.64578 500
なんでこんなことが起こっているの?dplyr
最大値を計算する理由は、行に対して1回ではなく、グループに対して1回だけですか?
編集:で単一のmutate
ステートメントを使用add_tte
し、より大きな例を作成したとしても、add_tte_old
それでも高速です
# these are the only lines of code modified, the rest is as before
nsamples <- 10000
foo <- data.frame(engine = rep(seq(1, ngroups), each = nsamples), cycles = runif(ngroups*nsamples, 0, nsamples))
add_tte <- function(dataset){
dataset %<>% group_by(engine) %>% mutate(max_cycles = max(cycles), tte = max_cycles - cycles) %>%
select(-max_cycles) %>% ungroup
}
# the new results are:
microbenchmark(add_tte(foo), add_tte_old(foo), times = 500)
# Unit: milliseconds
# expr min lq mean median uq max neval
# add_tte(foo) 90.46658 107.14015 139.13570 131.83689 158.24358 411.3272 500
# add_tte_old(foo) 39.38357 46.13531 62.57386 52.00782 69.26815 176.1512 500
あなたはいくつかの間違った仮定をしました、しかしそれ以外に、もっと重要なことに、あなたは同じように比較していません。
以下の2つのバリアントを確認する方が理にかなっています。
add_tte <- function(dataset) {
dataset %<>% group_by(engine) %>% mutate(max_cycles = rep(max(cycles), times = n()), tte = max_cycles - cycles) %>%
select(-max_cycles) %>% ungroup
}
add_tte_old <- function(dataset) {
dataset %<>% group_by(engine) %>% mutate(extra = rep(1, times = n()), tte = max(cycles) - cycles) %>%
select(-extra) %>% ungroup
}
microbenchmark(add_tte(foo), add_tte_old(foo), times = 100)
私のマシンでは、これら2つはかなり似ています。
を事前に計算しようとする方法でmax(cycles)
、おそらく避けようとしていたことをしたのは皮肉なことです:)
この場合、実際には明示的rep()
に列を埋める必要がありますが、減算でmax(cycles) - cycles
は自動リサイクルで問題ありません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加