base と Tidyverse と data.table と
「恋しさと せつなさと 心強さと」といえば『ストリートファイターII MOVIE』の挿入歌ですね。
さて、初心者にRを教えるとき、base準拠にすべきか、Tidyverse準拠にすべきか、という議論があります。
これは私も悩むところでありまして、さらに言えば data.table ってのもあります。
んで、まずはこの三つの流派(?)が存在してそれぞれこんな書き方をするんだよ、というのを示せるといいのかなーと思うわけです。
そこで試しにこんな処理を base, Tidyverse, data.tableのそれぞれで書いてみました。
こんな風に書いてみましたが、それぞれの書き方の違いの雰囲気ぐらいは伝わるかな?
base
library(nycflights13) flights.df <- na.omit(as.data.frame(flights)[, c("dep_delay", "arr_delay", "carrier", "air_time", "distance")]) flights.df$HourlySpeed <- (flights.df$distance * 1.60934) / (flights.df$air_time / 60) flights.df2 <- aggregate( flights.df[, c("dep_delay", "arr_delay", "HourlySpeed") ], list(carrier = flights.df$carrier), mean ) flights.df2$n <- table(flights.df$carrier) flights.df2[order(flights.df2$n, decreasing = TRUE), ]
Tidyverse
library(nycflights13) library(tidyverse) flights %>% select(dep_delay, arr_delay, carrier, air_time, distance) %>% drop_na() %>% mutate(HourlySpeed = (distance * 1.60934) / (air_time / 60)) %>% group_by(carrier) %>% summarise( mean_dep_delay = mean(dep_delay), mean_arr_delay = mean(arr_delay), mean_HourlySpeed = mean(HourlySpeed), n = n() ) %>% arrange(desc(n))
data.table
library(nycflights13) library(data.table) flights.dt <- na.omit(as.data.table(flights)[, c("dep_delay", "arr_delay", "carrier", "air_time", "distance")]) setorder(flights.dt[ , HourlySpeed := (distance * 1.60934) / (air_time / 60) ][ j = list( mean_dep_delay = mean(dep_delay), mean_arr_delay = mean(arr_delay), mean_HourlySpeed = mean(HourlySpeed), n = .N ), by = carrier ], -n) -> flights.dt2 flights.dt2
実行速度は?
data.table圧勝!……かと思いきや、これくらいのデータ量だとTidyverseと大差ないですね。