2016-08-08 56 views
1
reduzieren

Ich versuche derzeit, die Werte in einer Spalte um einen bestimmten Gesamtbetrag zu reduzieren, bis dieser Betrag Null erreicht. Zum Beispiel in dem Datenrahmen durch diesen Code erstellt:Sequentiell Werte in einer Spalte in R

df = data.frame(matrix(0,nrow=10,ncol=2)) 
colnames(df) <- c("AccountNumber", "BuyAmount") 
overbuy <- 500000 
df$AccountNumber <- seq(1:10) 
df$BuyAmount <- c(35000, 220000, 240000, 0, 195000, 55000, 0, 280000, 65000, 105000) 

>df 
    AccountNumber BuyAmount 
1    1  35000 
2    2 220000 
3    3 240000 
4    4   0 
5    5 195000 
6    6  50000 
7    7   0 
8    8 280000 
9    9  65000 
10   10 105000 

Ich versuche, die Werte ungleich Null in der BuyAmount Spalte von 5000 zu einem Zeitpunkt, laufen entlang der Säule und die Verringerung des Wertes von overbuy von 5000 zu reduzieren jeden Zeit. Nach dem ersten Lauf durch die Schleife sollte df wie so aussehen:

>df 
    AccountNumber BuyAmount 
1    1  30000 
2    2 215000 
3    3 235000 
4    4   0 
5    5 190000 
6    6  45000 
7    7   0 
8    8 275000 
9    9  60000 
10   10 100000 

Und der Wert von overbuy sollte von 40000 bis 460000. reduziert werden würde ich diese Schleife wie diese Werte zu überfahren fortzusetzen, bis overbuy 0 erreicht . theoretisch wäre df als

>df 
    AccountNumber BuyAmount 
1    1   0 
2    2 150000 
3    3 170000 
4    4   0 
5    5 130000 
6    6   0 
7    7   0 
8    8 210000 
9    9   0 
10   10  35000 

einmal zu viel kaufen 0 ist Mein aktueller Versuch erreicht Ende:

while(overbuy > 0){ 
    for(1 in 1:10){ 
    ifelse(df$BuyAmount[i] != 0, df$BuyAmount[i] <- df$BuyAmount[i] - 5000, "") 
    overbuy <- overbuy - 5000 
    } 
} 

Jede mögliche Hilfe würde geschätzt!

+0

Welche Art von Analyse durchführen Sie? Es gibt definitiv Teile von 'dplyr', die Ihren Code eleganter machen könnten, aber es würde helfen, das Gesamtbild zu verstehen. –

+0

Ich habe derzeit einen Code, der mir einen Gesamtbetrag für jedes Konto zu kaufen, aber es in der Regel um einige tausend Dollar aufgrund Rundungsfehler überschwingt (jede Bestellung kann nur in Schritten von 5000 $ platziert werden). Ich möchte diese Überschreitung systematisch reduzieren, um sicherzustellen, dass ich nicht in jedem Konto überbezahlen und es in Lastschrift setzen muss. Ich habe oben ein extremes Beispiel verwendet, um zu zeigen, dass, sobald ein Wert 0 erreicht, er von den restlichen Iterationen ausgeschlossen werden sollte. – Nick

+0

Wäre es sinnvoller, den Preis zu reduzieren, bis es eine durch 5000 teilbare Zahl wäre? Auf diese Weise erhalten Sie den günstigsten Gebotspreis, ohne den Wert zu überschreiten. –

Antwort

1

Ich denke, das funktioniert, aber es ist nicht elegant und ich könnte Ihr Ziel nicht vollständig verstanden haben. Wenn nicht, lass es mich wissen und ich werde das beheben.

EDITED:

while(overbuy > 0){ 
    for(i in 1:10){ 

     if(df$BuyAmount[i]!=0){ 
      overbuy <- overbuy - 5000 
     } 
     df$BuyAmount[i] <- pmax(0, df$BuyAmount[i] - 5000) 

     print(overbuy) 
     print(df) 
     if(overbuy == 0) break 
    } 
} 
+0

Ich füge hinzu, dass die endgültige df, die ich bekomme, nicht genau das gleiche wie Ihre erwartete Ausgabe ist. Aber ich denke, das folgt der Logik Ihrer Frage, also liegt vielleicht der Fehler in Ihren Berechnungen? – mkt

+0

Ich denke, das ist immer noch auf 0 Elemente iterieren, anstatt sie zu überspringen, aber es ist sicherlich nah dran. Es sieht so aus, als würde es alle 10 Elemente durchlaufen und die Maxima von 0 oder -5000 bei der Arbeit an einem Element == 0 zurückgeben, wo ich denke, dass die Diskrepanz kommt. – Nick

+0

Sie haben Recht, mein Fehler. Bearbeitet. – mkt

1

@mkt sieht aus wie Sie nur eine Zeile benötigt, if(df$BuyAmount[i] <= 0) next

while(overbuy > 0){ 
    for(i in 1:10){ 
    if(df$BuyAmount[i] <= 0) next 
    df$BuyAmount[i] <- pmax(0, df$BuyAmount[i] - 5000) 
    overbuy <- overbuy - 5000 
    print(overbuy) 
    print(df) 
    if(overbuy == 0) break 
    } 
    if(overbuy == 0) break 
}