2017-05-16 2 views
1

Ich führe einige Berechnungen durch, bei denen das Ergebnis einer Zeile die Eingabe für die nächste Zeile ist.Berechnung basierend auf vorherigen Zeilenergebnissen in dplyr

Ich verwende eine for-Schleife, die ziemlich langsam ist, gibt es eine Möglichkeit, dplyr für diese Arten von Berechnungen zu verwenden? Beispiel unten

df <- data.frame(beginning_on_hand = c(10,0,0,0,0,0,0,0,0,0,0,0), 
        sales = c(10,9,4,7,3,7,2,6,1,5,7,1), 
        ship = c(10,9,4,7,3,7,2,6,1,5,7,1)) 

dfb <- df %>% 
     mutate(receipts = 0) %>% 
     mutate(ending_on_hand = 0) %>% 
     mutate(receipts = lag(ship, 2)) %>% 
     mutate(receipts = if_else(is.na(receipts), 0, receipts)) 

> dfb 
    beginning_on_hand sales ship receipts ending_on_hand 
       10 10 10  0    0 
        0  9 9  0    0 
        0  4 4  10    0 
        0  7 7  9    0 
        0  3 3  4    0 
        0  7 7  7    0 
        0  2 2  3    0 
        0  6 6  7    0 
        0  1 1  2    0 
        0  5 5  6    0 
        0  7 7  1    0 
        0  1 1  5    0 

for(i in 1:(nrow(dfb)- 2)) { 
    dfb$ending_on_hand[i] <- dfb$beginning_on_hand[i] + dfb$receipts[i] - dfb$sales[i] 
    dfb$beginning_on_hand[i+1] <- dfb$ending_on_hand[i] 
} 

> dfb 
    beginning_on_hand sales ship receipts ending_on_hand 
1     10 10 10  0    0 
2     0  9 9  0    -9 
3     -9  4 4  10    -3 
4     -3  7 7  9    -1 
5     -1  3 3  4    0 
6     0  7 7  7    0 
7     0  2 2  3    1 
8     1  6 6  7    2 
9     2  1 1  2    3 
10     3  5 5  6    4 
11     4  7 7  1    0 
12     0  1 1  5    0 
+1

Werfen Sie einen Blick auf 'dplyr :: lag()' – Phil

+0

Sind Ihre letzten zwei Zeilen am Ende Empfang annehmen, -2 und 2? '4 + 1 - 7 = -2' und' -2 + 5 - 1 = 2' – akash87

Antwort

0

Ich habe keine dplyr Lösung für diese, aber hier ist eine data.table Lösung.

df <- data.frame(beginning_on_hand = c(10,0,0,0,0,0,0,0,0,0,0,0), 
       sales = c(10,9,4,7,3,7,2,6,1,5,7,1), 
       ship = c(10,9,4,7,3,7,2,6,1,5,7,1)) 

dfb <- df %>% 
    mutate(ending_on_hand = 0) %>% 
    mutate(receipts = lag(ship, 2)) %>% 
    mutate(receipts = if_else(is.na(receipts), 0, receipts)) 

dfb<-data.table(dfb) 
df.end <- dfb[, ending_on_hand := cumsum(beginning_on_hand + receipts - sales)][, 
       beginning_on_hand := beginning_on_hand + lag(ending_on_hand, default = 0)] 

>df.end 
    beginning_on_hand sales ship ending_on_hand receipts 
1:    10 10 10    0  0 
2:     0  9 9    -9  0 
3:    -9  4 4    -3  10 
4:    -3  7 7    -1  9 
5:    -1  3 3    0  4 
6:     0  7 7    0  7 
7:     0  2 2    1  3 
8:     1  6 6    2  7 
9:     2  1 1    3  2 
10:     3  5 5    4  6 
11:     4  7 7    -2  1 
12:    -2  1 1    2  5 

Um zu erklären, listet data.table verwendet grundsätzlich die Daten umfassen und zeigt sie in der Regel eine Flat-File-Weise. Es verwendet SQL-Anweisungen zum Organisieren und Verarbeiten von Daten. Die hier verwendeten Funktionen sind cumsum und lag. cumsum berechnet alle Werte vor einem bestimmten Index und lag sucht nach einem Wert über oder vor einem bestimmten Index.

Verwandte Themen