2016-04-07 8 views
0

Ich habe Probleme beim Verweisen auf Bedingungen, die in mehreren Zeilen mit einer for-Schleife stattfinden.Verweis auf Bedingungen in mehreren Zeilen (für Schleife)

Die Idee ist wie folgt. Es gibt einen Datenrahmen mit Spalten LastPrice und KCT. Möchte SignalBinary Spalt zu dem Datenrahmen, und wenn

1) LastPrice [j]> KCT [j] in 3 beliebigen aufeinanderfolgenden Reihen, &

2) LastPrice [j + 1] addieren - LastPrice [j + 1 + 3]> 12 in einer der Zeilen j + 1 bis j + 1 + 10 (dh 10 Zeilen darunter)

wollen dann eine 1 in SignalBinary [i] aufnehmen.

df <- data.frame(nrow =20, ncol =2) 
df <- data.frame(LastPrice = c(1221,1220,1220,1217,1216,1218,1216,1216,1217,1220,1219,1218,1220,1216,1217,1218,1218,1207,1206,1205), KCT = c(1218,1218,1219,1218,1221,1217,1217,1216,1219,1216,1217,1216,1219,1217,1218,1217,1217,1217,1219,1217)) 
df$SignalBinary <-for(j in1:20){for(i in1:10){ifelse (df$LastPrice[j]> df$KCT[j]& df$LastPrice[j+1]> df$KCT[j+1]& df$LastPrice[j+2]> df$KCT[j+2]& df$LastPrice[j+i]- df$LastPrice[j+i+3]>12,1,0)}} 

basierend auf den Daten, wäre der Code erwartet, dass eine 1 in den Zeilen 10 und 11 und 0en in den Rest aufzuzeichnen. Aber ich mache etwas falsch. Das Ausführen des Codes gibt keine Fehlermeldung, aber es erstellt kein df $ SignalBinary. Das Ausführen von df $ SignalBinary sagt NULL.

BTW der Zweck ist, den Code auf eine große Datenbank von Preisen anzuwenden, um Statistiken über binäre Signale laufen zu lassen.

Hoffe jemand kann helfen. Vielen Dank

+0

ein Problem hier ist, darüber nachzudenken, wenn i = 20 und j = 10, wenn Sie Zugriff auf df $ LastPrice [j + i ]. Sie versuchen, aus einem Datensatz mit nur 20 Zeilen auf Zeile 30 zuzugreifen. ifelse() wirft keinen Fehler auf diese –

+0

Sie haben Recht. Aber ich weiß leider nicht, wie ich das beheben soll. – Krug

Antwort

0

Gelöst! Buchung der Lösung War wesentlich komplizierter als ich dachte. Musste die Größe des StrongMove von 12 auf 3 ändern sonst würde man keine Signale bekommen angesichts der Daten die ich in diesem Beispiel bereitgestellt habe.

#Data 
df <- data.frame(LastPrice = c(1221, 1220, 1220, 1217, 1216, 1218 , 1216, 1216, 1217, 1220, 1219, 1218, 1220, 1216, 1217, 1218, 1218, 1207, 1206, 1205), KCT = c(1218, 1218, 1219, 1218, 1221, 1217 , 1217, 1216, 1219, 1216, 1217, 1216, 1219, 1217, 1218, 1217, 1217, 1217, 1219, 1217)) 

#Define inputs 
StrongMoveWindow = 10  # up to this far below the current row 
StrongMoveDur = 3   # check row against another this far down 
StrongMoveSize = 3  # for a difference at least this big 
PvsKCTDur = 3 

#Set variables and define loop boundaries 
base_rows = 1:(nrow(df) - StrongMoveDur) # can't check more than this 
candidate_max = pmin(base_rows + StrongMoveWindow, nrow(df) - StrongMoveDur) # for a given base row, this is the maximum row to start checking against 
df$StrongMove = rep(NA, nrow(df)) 
df$SignalBinary = rep(NA, nrow(df)) # pre-allocate a vector of results 

#Make StrongMove variable 
for (i in seq_along(base_rows)) { 
    df$StrongMove[i] = as.numeric(
    any(
     df$LastPrice[(i + 1):candidate_max[i]] - 
     df$LastPrice[((i + 1):candidate_max[i]) + StrongMoveDur] > StrongMoveSize))} 

#Make ContPvsKCT variable 
library(data.table) 
setDT(df) 
df[, SingPvsKCT := as.integer(LastPrice > KCT)] 
df[, ContPvsKCT := do.call(pmin, shift(SingPvsKCT, 0:(PvsKCTDur-1), type="lead"))] 

#Make SignalBinary variable 
df$SignalBinary <- ifelse (df$ContPvsKCT == 1 & df$StrongMove == 1, 1, 0) 

Big dank @Gregor @HubertL @ Chris @Psidom @brittenb @Frank

0

Eine Sache, die falsch ist, ist, dass Sie nichts aus Ihrer ifelse-Anweisung zurückgeben (Sie haben derzeit 1 und 0 als Aktionen, wenn eine Bedingung erfüllt ist). Ich denke (aber zitieren Sie mich nicht), dass ich Ihr Problem auf eine einfachere Weise gelöst habe, ohne die Verwendung von verschachtelten for Schleifen.

df <- data.frame(nrow = 20, ncol = 2) 
df <- data.frame(LastPrice = c(1221, 1220, 1220, 1217, 1216, 1218 , 1216, 1216, 1217, 1220,  1219, 1218, 1220, 1216, 1217, 1218, 1218, 1207, 1206, 1205), KCT = c(1218, 1218, 1219, 1218, 1221, 1217 , 1217, 1216, 1219, 1216, 1217, 1216, 1219, 1217, 1218, 1217, 1217, 1217, 1219, 1217)) 

df$SignalBinary <- as.numeric(df$LastPrice >= df$KCT & 
         c(rep(FALSE ,3), diff(df$LastPrice, lag=3) >= 3)) 

Also habe ich zwei Bedingungen, die für den Vektor erfüllt werden müssen. Zuerst muss df$LastPrice größer als (oder gleich) df$KCT sein. Zweitens muss der verzögerte Unterschied zwischen df$LastPrice größer oder gleich 3 sein. Ich puffe die ersten 3 Werte mit FALSE auf, um die zwei Vektoren von vergleichbarer Länge zu erhalten. Wenn beide Bedingungen erfüllt sind, zeichnet es TRUE auf, die ich in numerisch umwandle und dann die neue Spalte in data.frame platziere.

Ersetzen Sie einfach die Werte in Ihrem Spielzeugbeispiel durch die Werte, die Sie für Ihre Anwendung benötigen, und ich denke, das sollte funktionieren.

+0

Vielen Dank für die Hilfe !! Wenn Sie "diff" verwenden, wird der Unterschied zwischen einer Zeile und drei vorherigen Zeilen unterschieden. Ich brauche den Unterschied zwischen einer Zeile und jeder der drei vorherigen Zeilen. Könnte die Diff-Funktion 3 mal wiederholen, aber nur das vereinfachte Problem, das hier präsentiert wird, vergleicht mit 3. In Wirklichkeit wollen wir gegen mindestens 20, in einigen Fällen viel mehr vergleichen, also denke nicht, dass es einen Weg um die for-Schleife gibt. Außerdem haben Sie die dritte (knifflige) Bedingung weggelassen (d. H., Sie suchen nach der Differenz nur in den 10 vorherigen Zeilen und nicht in jeder Zeile).Danke jedenfalls, gab mir etwas zum Nachdenken. – Krug

Verwandte Themen