I have numerous datasets that will eventually be compared against one another. I've read that data.table and using lapply was the fastest way to analyze the data and saw some benchmark comparisons in the posts. I've noticed it lag a little as the datasets get larger and did some benchmarking and it was considerably slower than just using "summarize". Including a very basic table and code in case I am missing something on how to optimize the data.table speed.
ARM <- rep(seq(1:10), 10000)
TEST <- rep(seq(1:100), 1000)
TIME <- rep(seq(1:5), 20000)
SEX <- rep(1:2, 50000)
RESULTS <- rnorm(100000, mean = 50, sd = 10)
tst <- as.data.frame(cbind(ARM, TEST, TIME, SEX, RESULTS))
tstdt <- as.data.table(tst)
setDT(tstdt)
microbenchmark(tstdt[,.(n = .N), by = list(ARM, TEST, TIME, SEX)],
tst %>% group_by(ARM, TEST, TIME, SEX) %>% summarize(mean = mean(TEST),n = n()),
tstdt[,(lapply(.SD, mean)), by = .(ARM, TEST, TIME, SEX), .SDcols = "TEST"])
That results with the summarize method being the fastest by quite a bit.
min lq mean median uq max neval
1 19.65800 21.841651 23.75156 22.585946 23.572930 43.24424 100
2 8.01111 8.487736 9.36991 8.852225 9.451928 19.27691 100
3 22.43461 23.452590 25.07495 24.179198 25.047663 85.74855 100
Any information on how to optimize data.tables or help with where I went wrong would be appreciated.
Suggested larger data and code for benchmarking, including configurably larger data, fewer runs, not using .SDcols, and taking the mean of the RESULTS column.
library(dplyr)
library(data.table)
n = 5e6
ARM <- rep(seq(1:10), n / 10)
TEST <- rep(seq(1:100), n / 100)
TIME <- rep(seq(1:5), n / 5)
SEX <- rep(1:2, n / 2)
RESULTS <- rnorm(n, mean = 50, sd = 10)
tst <- data.frame(ARM, TEST, TIME, SEX, RESULTS)
tstdt <- as.data.table(tst)
setDT(tstdt)
microbenchmark::microbenchmark(
dplyr = tst %>% group_by(ARM, TEST, TIME, SEX) %>% summarize(mean = mean(RESULTS),n = n()),
dt = tstdt[, .(mean = mean(RESULTS), n = .N), by = .(ARM, TEST, TIME, SEX)],
times = 10
)