y <- cumsum(x)[cumsum(v)]
y <- c(y[1], diff(y))
Похоже, что он выполняет дополнительную работу, потому что он вычисляет сумму для всего вектора, но на самом деле он быстрее, чем другие решения, как для небольшого, так и для большого числа групп.
Вот как я смоделировал данные
set.seed(5)
N <- 1e6
n <- 10
x <- round(runif(N,0,100),1)
v <- as.vector(table(sample(n, N, replace=TRUE)))
На моей машине время с n <- 10
:
- Брэндон Бертельсен (для петли): 0,017
- Рамнатх (строка): 0,057
- Джон (разделить / применить): 0,280
- Аарон (cumum): 0,008
меняется на n <- 1e5
время:
- Брэндон Бертельсен (для петли): 2,181
- Рамнатх (строка): 0,226
- Джон (разделить / применить): 0,852
- Аарон (сумма): 0,015
Я подозреваю, что это быстрее, чем делать умножение матриц, даже с разреженным матричным пакетом, потому что не нужно формировать матрицу или делать какие-либо умножения. Если требуется больше скорости, я подозреваю, что это можно было бы ускорить, написав ее на C; не сложно сделать с пакетами inline
и rcpp
, но я оставлю это вам.