Множественные кумулятивные суммы [дубликаты]

Надеюсь, название достаточно ясное.

У меня есть таблица, выглядящая так:

classes id value
a       1  10
a       2  15
a       3  12
b       1  5
b       2  9
b       3  7
c       1  6
c       2  14
c       3  6

а вот что хотелось бы:

classes id value cumsum
a       1  10    10
a       2  15    25
a       3  12    37
b       1  5     5
b       2  9     14
b       3  7     21
c       1  6     6
c       2  14    20
c       3  6     26

Я видел это решение и уже успешно применил его к случаям, когда у меня нет нескольких классов:

id value cumsum
1  10    10
2  15    25
3  12    37

Это было достаточно быстро, даже с наборами данных, размер которых эквивалентен тому, над которым я сейчас работаю.

Однако, когда я пытаюсь применить тот же самый код к набору данных, над которым я сейчас работаю (который выглядит как первая таблица этого вопроса, несколько классов IE), без подстановки его на a, b, c, мне кажется что это занимает много времени (он работает уже 4 часа. Набор данных составляет 40 000 строк).

Есть идеи, есть ли проблема с кодом из связанного ответа при использовании в этом контексте? У меня проблемы с треугольным соединением, но я чувствую, что может быть проблема с размером соединения когда количество строк увеличивается, что сильно замедляет все это, что, возможно, даже усугубляется тем фактом, что существует несколько «классов», по которым можно выполнять кумулятивные суммы.

Есть ли способ сделать это быстрее? Я использую SQL в R через пакет SQLDF. Подойдет решение либо в коде R (с внешним общим пакетом или без него), либо в коде SQL.

Спасибо


person François M.    schedule 11.02.2016    source источник
comment
Какую базу данных вы используете? Пожалуйста, пометьте соответствующим образом.   -  person Gordon Linoff    schedule 11.02.2016
comment
В базе R это будет with(df, ave(value, classes, FUN = cumsum))   -  person talat    schedule 11.02.2016
comment
За закрытое голосование, не зная, каким образом его следует обмануть   -  person Tensibai    schedule 11.02.2016


Ответы (2)


В SQL вы можете вычислить кумулятивную сумму, используя стандартную функциональность ANSI sum() over ():

select classes, id, value,
       sum(value) over (partition by classes order by id) as cumesum
from t;
person Gordon Linoff    schedule 11.02.2016
comment
Пакет sqldf использует sqlite, поэтому вышеприведенное может не работать. Соответствующий пост: stackoverflow .com/questions/4074257/ - person zx8754; 11.02.2016
comment
sqldf использует sqlite по умолчанию, но sqldf может использовать PostgreSQL, и в этом случае вышеописанное должно работать. - person G. Grothendieck; 16.02.2016

Или вы можете использовать by из пакета base:

df$cumsum <- unlist(by(df$value, df$classes, cumsum))
#  classes id value cumsum
#1       a  1    10     10
#2       a  2    15     25
#3       a  3    12     37
#4       b  1     5      5
#5       b  2     9     14
#6       b  3     7     21
#7       c  1     6      6
#8       c  2    14     20
#9       c  3     6     26
person mtoto    schedule 11.02.2016
comment
На самом деле это не работает (может быть, я делаю что-то не так). Я не уверен, но кажется, что это кумулятивно по всему, а не by по каждому классу. Вот что я делаю: df[with(df, order(classes, another_value, decreasing = TRUE))], а затем df$cumsum <- unlist(by(df$value, df$classes, cumsum)) - person François M.; 18.05.2016
comment
Что такое another_value? Код работает с вашим примером набора данных. - person mtoto; 18.05.2016
comment
another_value - это id, например, столбец, по которому я хочу заказать. (NB: есть еще одна проблема, это не кумулятивная сумма по столбцу value...) - person François M.; 18.05.2016
comment
Вы можете задать новый вопрос, предоставив пример данных и код. - person mtoto; 18.05.2016