2017-06-26 1 views
1

Ich versuche, die folgenden durch die Verwendung für und verschachtelt, wenn in r zu lösen: meine Daten für Preis verfügbar: test20 insbesondere um Austausch mit geschachtelten wenn und Schleife in r

test2 <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 399, 0, 0, 399, 0, 0, 0, 0, 399, 0, 0, 0, 0, 429, 0, 429, 
0, 0, 0, 499, 0, 429, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0) 

das Problem: 0 vor dem ersten Auftreten des Preises mit dem Wert des ersten Auftretens zu ersetzen, dann 0 nach dem ersten Auftreten mit dem Wert des ersten Auftretens bis zum zweiten Auftreten des Preises und so weiter zu ersetzen. Die 0 nach dem letzten Auftreten des Preises sollte durch den Wert des letzten Auftretens ersetzt werden.

Ich habe den folgenden Code verwendet:

priceposition2 <- which(test2>0) 
for(i in 1:length(priceposition2)){ 
for(m in 1:length(test2)){ 
    if (m <= priceposition2[1]){ 
test2[m] <- test2[priceposition2[1]] 
} else if (m > priceposition2[1]){ 
    if (m> priceposition2[i] && m < priceposition2[i+1]){ 
    test2[m] <- test2[priceposition2[i]] 

    }else if(m> priceposition2[length(priceposition2)]){ 
    test2[m] <- test2[priceposition2[length(priceposition2)]] 
    } 

} 
m=m+1 
} 
i=i+1 
} 

ich folgendes Ergebnis danach erhalten:

[1] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 
399 399 399 399 399 
[24] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 
399 399 399 399 399 
[47] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 
399 399 399 399 399 399 
[70] 399 399 399 399 399 399 399 399 429 429 429 429 429 429 499 499 429 429 
429 429 429 429 529 
[93] 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 
529 529 529 529 529 
[116] 529 529 529 529 529 529 529 529 529 529 529 529 529 529 

das ist genau das, was ich will. Das Problem ist, ich Fehler erhalten, indem Sie den obigen Code verwenden:

Error in if (m > priceposition2[i] && m < priceposition2[i + 1]) { : 
missing value where TRUE/FALSE needed 

Gibt es etwas, das ich falsch mache? Gibt es auch eine Alternative mit Apply-Familie für das oben genannte Problem?

+0

plese Verwendung dput(), um Ihre Daten zu teilen –

Antwort

3

Sie könnten na.locf aus Paket zoo verwenden, um dies zu tun. Grundsätzlich möchten Sie zuerst alle Nullen durch NA ersetzen. Dann verwenden Sie na.locf Forwards mit na.rm = FALSE, um führende NAs zu behalten. Und dann na.locf rückwärts mit fromLast=TRUE verwenden, um die führenden NAs auf den ersten Wert zu ändern.

priceposition2<-c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,399,0,0,399,0, 
0,0,0,399,0,0,0,0,429,0,429,0,0,0,499,0,429,0, 
0,0,0,0,529,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) 

library(zoo) 
priceposition2[priceposition2==0] <- NA 
na.locf(na.locf(priceposition2,na.rm = FALSE),fromLast=TRUE) 

    [1] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 
[33] 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 399 
[65] 399 399 399 399 399 399 399 399 399 399 399 399 399 429 429 429 429 429 429 499 499 429 429 429 429 429 429 529 529 529 529 529 
[97] 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 529 
[129] 529 
+0

'na.locf (mit (priceposition2 , ifelse (priceposition2 == 0, NA_real_, priceposition2)), fromLast = TRUE) ' – Masoud

1

Sie können findInterval über den Indizes des gesamten Vektors verwendet werden, die Positionen der oben Null-Werte als die Grenzen Intervall verwenden. Dann verwenden Sie diese Intervallnummern, um die korrekten Werte über Null zu tauschen (wobei die erste für zwei Intervalle verwendet wird).

above_zero <- which(test2 > 0) 
carryover_from <- findInterval(seq_along(test2), c(0, above_zero)) 
carryover_values <- c(test2[above_zero[1]], test2[above_zero]) 
test2 <- carryover_values[carryover_from] 
3

Reduce in Basis R für gut geeignet ist, was nach sind (v ist Ihr Vektor):

Reduce(function(x,y) ifelse(y==0, x, y), v, accumulate=TRUE, init = v[v>0][1])[-1]