Общая сумма без учета текущей стоимости

Я новичок в R и пытаюсь написать функцию для кумулятивного суммирования ранее заказанных товаров клиентами. Я уже нашел почти подходящий пример кода на Stack Overflow, но у меня не получается модифицировать его под свои нужды.

Это код:

Fruits <- Fruits[order(Cars$order.id), ]  #sort data
Fruits$prev_Apples<-with(Fruits, 
    ave(
        ave(Apples, customer.id, FUN=cumsum),  #get running sum per customer.id
        interaction(customer.id, order.id, drop=T), 
    FUN=max, na.rm=T) #find largest sum per index per seg
)

А это кадр данных Fruits:

order.id   customer.id	Apples	 Peaches  Pears
1001	   J Car Ltd    	1   	0   	0
1002	    Som Comp    	0   	2   	0
1005	   Richardson   	0   	0   	1
1004	   J Car Ltd    	1   	0   	0
1003	   J Car Ltd    	2   	0   	0
1006	   Richardson   	1   	0   	1
1007	    Aldridge    	0   	0   	1
1008	   J Car Ltd    	0   	0   	1
1010	    Som Comp    	0   	1   	0
1009	   J Car Ltd	    1	    0	    0

Вот что я хотел бы получить:

order id	customer id	Apples	Peaches	Pears	Prev_Apples
1001	J Car Ltd	1	0	0	0
1002	Som Comp	0	2	0	0
1003	J Car Ltd	2	0	0	1
1004	J Car Ltd	1	0	0	3
1005	Richardson	0	0	1	0
1006	Richardson	1	0	1	0
1007	Aldridge	0	0	1	0
1008	J Car Ltd	0	0	1	4
1009	J Car Ltd	1	0	0	4
1010	Som Comp	0	1	0	0

И вот что я на самом деле получаю:

order id	customer id	Apples	Peaches	Pears	Prev_Apples
1001	J Car Ltd	1	0	0	1
1002	Som Comp	0	2	0	0
1003	J Car Ltd	2	0	0	3
1004	J Car Ltd	1	0	0	4
1005	Richardson	0	0	1	0
1006	Richardson	1	0	1	1
1007	Aldridge	0	0	1	0
1008	J Car Ltd	0	0	1	4
1009	J Car Ltd	1	0	0	5
1010	Som Comp	0	1	0	0

Итак, проблема в том, что cumsum включает в себя также текущий заказ яблок, в то время как я хотел бы, чтобы он включал только предыдущие заказы. Как мне изменить код? Любой ответ будет высоко оценен.


person gmt    schedule 04.12.2017    source источник
comment
Я не могу точно сказать, что происходит с вашими данными - пробелы в столбце. названия затрудняют. Не могли бы вы поделиться с dput(), чтобы его можно было копировать и вставлять? (И не используйте сниппеты — они не работают с R).   -  person Gregor Thomas    schedule 04.12.2017
comment
Похоже, вам нужен cumsum, где первый член равен 0, а последний член опущен. Попробуйте FUN = function(x) c(0, head(cumsum(x), -1))   -  person Gregor Thomas    schedule 04.12.2017
comment
Спасибо большое, это действительно то, что мне было нужно!   -  person gmt    schedule 04.12.2017


Ответы (1)


Предполагая, что вход воспроизводимо показан в примечании в конце, мы сортируем Fruits, фиксируя ошибочную ссылку на Cars, а затем используем ave с cumsum, вычитая текущее значение Apples из cumsum, отменяя последнее значение в сумме.

Это дает тот же ответ, что и ответ, указанный в вопросе.

Fruits <- Fruits[order(Fruits$order.id), ]
transform(Fruits, Prev_Apples = ave(Apples, customer.id, FUN = cumsum) - Apples)

давая:

   order.id customer.id Apples Peaches Pears Prev_Apples
1      1001   J Car Ltd      1       0     0           0
2      1002    Som Comp      0       2     0           0
5      1003   J Car Ltd      2       0     0           1
4      1004   J Car Ltd      1       0     0           3
3      1005  Richardson      0       0     1           0
6      1006  Richardson      1       0     1           0
7      1007    Aldridge      0       0     1           0
8      1008   J Car Ltd      0       0     1           4
10     1009   J Car Ltd      1       0     0           4
9      1010    Som Comp      0       1     0           0

Примечание. Предполагается, что ввод в воспроизводимой форме:

Fruits <- structure(list(order.id = c(1001L, 1002L, 1005L, 1004L, 1003L, 
1006L, 1007L, 1008L, 1010L, 1009L), customer.id = structure(c(2L, 
4L, 3L, 2L, 2L, 3L, 1L, 2L, 4L, 2L), .Label = c("Aldridge", "J Car Ltd", 
"Richardson", "Som Comp"), class = "factor"), Apples = c(1L, 
0L, 0L, 1L, 2L, 1L, 0L, 0L, 0L, 1L), Peaches = c(0L, 2L, 0L, 
0L, 0L, 0L, 0L, 0L, 1L, 0L), Pears = c(0L, 0L, 1L, 0L, 0L, 1L, 
1L, 1L, 0L, 0L)), .Names = c("order.id", "customer.id", "Apples", 
"Peaches", "Pears"), class = "data.frame", row.names = c(NA, 
-10L))
person G. Grothendieck    schedule 04.12.2017