############################################################################### # FAST VERSION — identical results, fully vectorised ############################################################################### profvis({ ## --- Fix 1: vectorised arithmetic (no loop, no regrowth) ------------------ doubled <- df$value * 2 ## --- Fix 2: operate on the column directly (no matrix coercion) ----------- df$normalized <- df$value / 100 ## --- Fix 3: one grouped pass at C level ----------------------------------- group_means <- tapply(df$value, df$group, mean) }) ############################################################################### # Same three fixes with other approach: # ############################################################################## library(dplyr) profvis({ group_means <- df |> group_by(group) |> summarise(m = mean(value)) }) system.time({ group_means <- df |> group_by(group) |> summarise(m = mean(value)) }) # library(data.table) profvis({ dt <- as.data.table(df) group_means <- dt[, .(m = mean(value)), by = group] }) system.time({ dt <- as.data.table(df) group_means <- dt[, .(m = mean(value)), by = group] })