Ersetzen fehlender Daten durch regressierte Werte<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Hallo
Ich habe eine Zeitreihe, für die die Variable fehlende Werte aufweist. Ich möchte die fehlenden Werte durch ein lineares Modell ersetzen, das aus den zeitlich nächsten verfügbaren Werten abgeleitet wird.
Was wäre der beste Weg?
Und wenn das Skript das mit allen Spalten meiner Tabelle (außer der Uhrzeit) machen könnte, wäre das sogar noch besser
Danke
Beispiel
Was ich habe
| T | Ausgabe |
|---|
| 0 | 10 |
| 1 | . |
| 2 | . |
| 4 | 30 |
| 10 | . |
| 20 | 10 |
Was ich möchte:
| T | Ausgabe |
|---|
| 0 | 10 |
| 1 | 15 |
| 2 | 20 |
| 4 | 30 |
| 10 | 22.5 |
| 20 | 10 |
Betreff: Fehlende Daten durch regressierte Werte ersetzenDie Funktionsweise von JMP-Formeln und JMP-Funktionen besteht darin, dass die zuletzt erstellte oder referenzierte Variable von der Formel oder Funktion übergeben wird. Daher wird in Ihrer Ersetzungsformel als Zeilenwert der Wert aus der „Werte“-Matrix zurückgegeben, der der Row()-Nummer entspricht. Und da in der „Werte“-Matrix die Spaltenwerte mit der Nachricht „<< Werte abrufen“ abgerufen wurden und die Interpolationen auf der „Werte“-Matrix durch Angabe vorgenommen wurden
Werte[Zeile()]
Die Formel verschiebt die Werte zeilenweise in die neue Spalte.
Eine andere Möglichkeit, dies zu erklären, besteht darin, den Prozessablauf der Formel durchzugehen
Alle Formeln durchlaufen alle Zeilen in einer Datentabelle von Zeile 1 bis zur letzten Zeile in der Datentabelle.
Bei der Verarbeitung von Zeile 1 werden alle Werte aus der Spalte „p (g/L)“ zur Verarbeitung in eine Matrix verschoben. Verarbeitungsschleifen von Element 1 in der Matrix bis zum Ende der Matrix, wobei bei Bedarf Interpolationen durchgeführt werden. Am Ende der Schleife sind alle Elemente der Matrix ausgefüllt. Dann wird der Wert aus dem ersten Element in der „Werte“-Matrix als der für die erste Zeile der Spalte zu verwendende Wert an die Formel zurückgegeben.
Dann wird der Zeilenwert verschoben, um die Formel für die 2. Zeile auszuführen, und die einzigen Anweisungen, die für die 2. Zeile ausgeführt werden, sind
Werte[Zeile()]
Dadurch wird der Formel der Wert der Zeile „Spalte 2“ zurückgegeben, bei dem es sich um Element 2 der „Werte“-Matrix handelt.
Die Formel setzt die Schleife für jede nachfolgende Zeile einmal fort und führt nur die Anweisung aus
Werte{Zeile()]
Ich hoffe das macht SinnBetreff: Fehlende Daten durch regressierte Werte ersetzenJim,
Vielen Dank. das funktioniert jetzt wirklich gut. Können Sie mir erklären, was die letzten „values[Row()];“ tut
Betreff: Fehlende Daten durch regressierte Werte ersetzenWenn Sie möchten, dass der Wert in der Spalte „Interpretiert“ gleich 0 ist, wenn der :Time-Wert 0 ist, würde eine Änderung des Codes wie unten funktionieren
For( i = 1, i <= N Rows( values ), i++,
If( :Time[i] == 0, values[i]=0); // **************
If( Is Missing( values[i] ),
counter++,
If( counter > 0,
For( k = 1, k <= counter, k++,
base = values[i - counter - 1];
incr = Abs( (base - values[i]) / (counter + 1) );
If( base < values[i],
values[(i - counter - 1) + k] = base + k * incr,
values[(i - counter - 1) + k] = base - k * incr
);
);
counter = 0;
)
)
);Betreff: Fehlende Daten durch regressierte Werte ersetzenDas gilt für den ersten Wert, aber was ich brauche ist, dass alles „Zeit“ 0 ist, der interpolierte Wert ist Null. Die Zeitspalte enthält mehrere Nullen
Betreff: Fehlende Daten durch regressierte Werte ersetzenIst es anhand des Codes, den ich Ihnen zur Verfügung gestellt habe, das, wonach Sie fragen?
If( Is Missing( values[1] ),
values[1] = 0
);Betreff: Fehlende Daten durch regressierte Werte ersetzenJim,
Ich habe das Drehbuch zum Laufen gebracht. Ich musste etwas Mathematik hinzufügen, um die Delta-Zeit sowohl für die Inkr-Berechnung als auch für die Interpolationsauswertungsschleife zu berücksichtigen. Das letzte Problem besteht darin, dass ich, da ich vorhabe, mehrere Ausführungsdateien zusammenzufügen und das Skript auszuführen, mehrere Stellen habe, an denen Zeit = 0 ist (Zeit: 0,12,24,48,0,12,24,48 ... ), daher sollte der erste interpolierte Wert für den angegebenen Datenblock 0 sein. Ich bin mir nicht sicher, wie ich das mit der Matrixnotation machen soll.
Betreff: Fehlende Daten durch regressierte Werte ersetzenMeiner Erfahrung nach hatte ich zu viele Probleme beim Versuch, auf die eigentliche Formelspalte innerhalb der Formel zu verweisen. Somit ist der Ansatz dargestellt. Ich habe mich auch mit Ihrer Formel beschäftigt, und zwar unter dem Gesichtspunkt, wie oft Sie die Daten mit Ihrer For()-Schleife durchlaufen. Meine Methode durchläuft die Datentabelle nur einmal, ohne die Iterationsersetzung.Betreff: Fehlende Daten durch regressierte Werte ersetzenJim,
Vielen Dank, ich werde es versuchen. Ich bin allerdings neugierig; Als ich zum ursprünglichen Skript zurückkehrte, dachte ich, dass der rekursive Fehler von Zeile 3 käme, weil er den Inkr berechnen würde und rows-counter-1 = 3-2-1 =0 erhalten würde. Ich würde die Fehlermeldung ignorieren und der Rest der Spalte wird erfolgreich interpoliert, mit Ausnahme des Endes.Das Hinzufügen weiterer Daten zur zu interpolierenden Tabelle verringert das Problem. Ich dachte, es könnten getrennte Probleme sein.
Betreff: Fehlende Daten durch regressierte Werte ersetzenWenn Sie versuchen, Werte innerhalb der Formelspalte selbst zu ändern, tritt ein rekursives Problem in der Formel auf.Ich habe Ihre Formel überarbeitet, um die gesamte Arbeit im Voraus mithilfe einer Matrix zu erledigen.Die resultierenden Werte werden dann für die einzelnen Zeilenwerte verwendet
Names Default To Here( 1 );
col_name_list = Current Data Table() << get column names( string );
If( !Contains( col_name_list, "Interpolated p (g/L)" ),
Current Data Table() << New Column( "Interpolated p (g/L)",
Numeric,
Continuous,
Formula(
dt = Current Data Table();
If( Row() == 1,
counter = 0;
values = dt:Name( "p (g/L)" ) << get values;
If( Is Missing( values[1] ),
values[1] = 0
);
counter = 0;
For( i = 1, i <= N Rows( values ), i++,
If( Is Missing( values[i] ),
counter++,
If( counter > 0,
For( k = 1, k <= counter, k++,
base = values[i - counter - 1];
incr = Abs( (base - values[i]) / (counter + 1) );
If( base < values[i],
values[(i - counter - 1) + k] = base + k * incr,
values[(i - counter - 1) + k] = base - k * incr
);
);
counter = 0;
)
)
);
);
values[Row()];
)
)
);Betreff: Fehlende Daten durch regressierte Werte ersetzenHier ist die Tabelle
Betreff: Fehlende Daten durch regressierte Werte ersetzenJim,
Danke für das Aufklären. Ich habe ein Problem mit dem Skript. Das letzte Intervall wird nicht ausgeführt und interpoliert.Ich kann nicht sagen, ob es etwas mit der Verschachtelung der Schleifen oder den „while“-Bedingungen zu tun hat. Grundsätzlich kann das letzte Intervall fehlender Daten unabhängig von der Tabellenlänge nicht ausgefüllt werden.
col_name_list = Current Data Table() << get column names( string );
If( !Contains( col_name_list, "Interpolated p (g/L)" ),
Current Data Table() << New Column(
"Interpolated p (g/L)",
Numeric,
Continuous,
Formula(
If(
Is Missing( :Name( "time (h)" ) ),
Empty(),
:name( "time (h)" ) == 0,
0,
!Is Missing( :Name( "p (g/L)" ) ),
:name( "p (g/L)" ),
dt = Current Data Table();
For( rows = 1, rows <= (N Rows( dt )), rows++,
If( Rows == 1, counter = 0 );
If( Is Missing( dt:name( "Interpolated p (g/L)" )[rows] ) == 1,
counter++);
If( counter > 0 & Is Missing( dt:name( "Interpolated p (g/L)" )[rows] ) == 0,
incr = (dt:name( "Interpolated p (g/L)" )[Rows] - dt:name( "Interpolated p (g/L)" )[Rows - counter - 1]) / (dt
:name( "time (h)" )[Rows] - dt:name( "time (h)" )[Rows - counter - 1]);
For( i = rows - counter, i <= rows - 1, i++,
dt:name( "Interpolated p (g/L)" )[i] = dt:name( "Interpolated p (g/L)" )[i - 1] + (incr * (dt:name( "time (h)" )[i]
-dt:name( "time (h)" )[i - 1]))
);
counter = 0;
);
);
)
)
)
);
Betreff: Fehlende Daten durch regressierte Werte ersetzenJMP unterscheidet in Funktionen und Anweisungen nicht zwischen Groß- und Kleinschreibung, also rows=RowsBetreff: Fehlende Daten durch regressierte Werte ersetzenJim,
Gibt es einen Unterschied zwischen „Zeilen“ und „Zeilen“? Könnten Sie es bitte erklären? Ich bin ein Anfänger.
Betreff: Fehlende Daten durch regressierte Werte ersetzenGuter Fang...sollte es sein
If this is row 1 initialize a variable named counter to 0
Betreff: Fehlende Daten durch regressierte Werte ersetzenDanke, es hat funktioniert!Du hast kommentiert
If this is row 1 initialize a variable named counter to 1
, meintest du „gegen 0“?
Betreff: Fehlende Daten durch regressierte Werte ersetzenHier ist eine aktualisierte/kommentierte Version meines Originalcodes.Alles, was Sie tun müssen, ist, den Spaltennamen von „Ausgabe“ in den Namen der Spalte zu ändern, in die Sie Werte ändern möchten.
// Set all default referenced memory variables to this unique application
Names Default To Here( 1 );
// Set the variable dt to be a pointer to the current active data table
dt = Current Data Table();
// Loop through the data table from row 1 to the last row and use a
// variable names "rows" as the index
For( rows = 1, rows <= N Rows( dt ), rows++,
// If this is row 1 initialize a variable named counter to 1
If( Rows == 1, counter = 0 );
// If the current row's value for the column named "Output" in the
// data table referenced by "dt" is missing (blank, null) increase
// the counter
If( Is Missing( dt:output[rows] ) == 1,
counter++
);
// If row is found with a non missing value for the column called Output,
// and the counter is > 0, which indicates previous rows with missing
// values, then calculate the required values and place them in their
// appropriate rows
If( counter > 0 & Is Missing( dt:output[rows] ) == 0,
// Calculate the incremental steps to use for the missing cells
incr = (dt:output[Rows] - dt:output[Rows - counter - 1]) / (counter + 1);
// Loop across the rows with missing values and fill in the data
For( i = Rows - counter, i <= Rows - 1, i++,
dt:output[i] = dt:output[i - 1] + incr
);
// reinitialize the counter
counter = 0;
);
);Betreff: Fehlende Daten durch regressierte Werte ersetzenTxnelson,
Könnten Sie das Skript mit Kommentaren aktualisieren? Ich bin neu bei JSL und brauche Hilfe, um zu verstehen, wie es auf mein Problem zutrifft. Ich habe den gleichen Bedarf wie OP, muss aber nur eine Spalte ausfüllen.Alternativ habe ich in der Vergangenheit den folgenden VBA-Code verwendet, um fehlende Daten in Excel auszufüllen. Ich habe mich gefragt, ob es in JSL etwas Ähnliches wie die Funktion End(xlDown).value gibt. Der Offset wird verwendet, um anzugeben, wo sich die Zeitpunktdaten befinden. Danke!
Sub interpolatedata()
For Each cell In Range("k4:k29")
If cell.Value = "" Then
y2 = cell.End(xlDown).Value
x2 = cell.End(xlDown).Offset(0, -8).Value
y1 = cell.End(xlUp).Value
x1 = cell.End(xlUp).Offset(0, -8).Value
x = cell.Offset(0, -8).Value
y = (y1) + (x - x1) * (y2 - y1) / (x2 - x1)
cell.Value = y
End If
Next
Betreff: Fehlende Daten durch regressierte Werte ersetzenGenau richtig bei MS,
Prost!
Betreff: Fehlende Daten durch regressierte Werte ersetzenIch hatte vor einigen Jahren ein ähnliches Problem und habe ein Skript geschrieben, um die Imputation durch „lokale Regression“ durchzuführen.
Hier ist eine aktualisierte Version:
dt = Current Data Table();
n = N Rows(dt);
x = Column(1);// Column("t")
For(i = 2, i <= N Col(dt), i++,
y = Column(i);
For Each Row(
If(1 < Row() < n & Is Missing(y[]),
// find previous non-missing row
Eval(Eval Expr(r1 = Max(dt << get rows where(!Is Missing(y[]) & Row() < Expr(Row())))));
// find next non-missing row
Eval(Eval Expr(r2 = Min(dt << get rows where(!Is Missing(y[]) & Row() > Expr(Row())))));
y[] = y[r1] + (y[r2] - y[r1]) / (x[r2] - x[r1]) * (x[] - x[r1]);
)
)
);
Betreff: Fehlende Daten durch regressierte Werte ersetzenHier ist ein Skript, das diese Aufgabe erledigt
Names Default To Here( 1 );
dt = Current Data Table();
For( rows = 1, rows <= N Rows( dt ), rows++,
If( Rows == 1, counter = 0 );
If( Is Missing( dt:output[rows] ) == 1,
counter = counter + 1,
If( counter > 0,
incr = (dt:output[Rows] - dt:output[Rows - counter - 1]) / (counter + 1);
For( i = Rows - counter, i <= Rows - 1, i++,
dt:output = dt:output[i - 1] + incr
);
counter = 0;
)
);
);
// Set all default referenced memory variables to this unique application
Names Default To Here( 1 );
// Set the variable dt to be a pointer to the current active data table
dt = Current Data Table();
// Loop through the data table from row 1 to the last row and use a
// variable names "rows" as the index
For( rows = 1, rows <= N Rows( dt ), rows++,
// If this is row 1 initialize a variable named counter to 1
If( Rows == 1, counter = 0 );
// If the current row's value for the column named "Output" in the
// data table referenced by "dt" is missing (blank, null) increase
// the counter
If( Is Missing( dt:output[rows] ) == 1,
counter++
);
// If row is found with a non missing value for the column called Output,
// and the counter is > 0, which indicates previous rows with missing
// values, then calculate the required values and place them in their
// appropriate rows
If( counter > 0 & Is Missing( dt:output[rows] ) == 0,
// Calculate the incremental steps to use for the missing cells
incr = (dt:output[Rows] - dt:output[Rows - counter - 1]) / (counter + 1);
// Loop across the rows with missing values and fill in the data
For( i = Rows - counter, i <= Rows - 1, i++,
dt:output[i] = dt:output[i - 1] + incr
);
// reinitialize the counter
counter = 0;
);
);Betreff: Fehlende Daten durch regressierte Werte ersetzenDanke Ron, aber ich sehe darin nichts, was eine Interpolation ermöglicht?
Betreff: Fehlende Daten durch regressierte Werte ersetzenVersuchen Sie dies für den Anfang
Imputation-Add-in