Letzte 30 Teile für jede Zeile und löschen Sie die anderen DatenHallo zusammen,
Ich habe eine Datentabelle mit mehreren Spalten und jede Spalte enthält eine unterschiedliche Anzahl von Zeilen mit Daten. Ich versuche einen Weg zu finden, die letzten 30 Zeilen der Daten in jeder Spalte abzurufen. Zum Beispiel hat Spalte 1 50 Zeilen und Spalte 2 75 Zeilen und ich möchte, dass jede Zeile die letzten 30 Zeilen mit Informationen enthält. Gibt es ein Skript, das das kann?
Automatisierung und SkripterstellungDatenmischung und -bereinigungMassenanpassungBetreff: Letzte 30 Teile für jede Zeile und die anderen Daten löschenFür zukünftige Leser dieses Titels eine Korrektur @Mark_Bailey Die Aussage zu seinem Code im Vergleich zum zweiten Teil des Codes aus der Antwort von @txnelson muss präzisiert werden.Die beiden Codeteile liefern die gleichen Ergebnisse, wenn davon ausgegangen wird, dass, sobald ein fehlender Wert gefunden wird, keine weiteren nicht fehlenden Werte in der Spalte erscheinen.@Mark_Bailey Code erfordert, dass die Mindestanzahl nicht fehlender Werte vorhanden sein muss, während @txnelson-Code dies nicht tut
Betreff: Letzte 30 Teile für jede Zeile und die anderen Daten löschenFWIW, hier ist noch eine weitere Version mit Matrizen:
NamesDefaultToHere(1);
// Make a data table 'dt', to play with.
nr = 100; // Number of rows
nc = 30; // Number of columns
p = 0.7; // Proportion of missing values
vals = J(nr*nc, 1, RandomInteger(0, 99));
makeMissing = RandomIndex(nr*nc, Floor(nr*nc*p));
vals[makeMissing] = .;
dt = AsTable(Shape(vals, nr, nc));
dt << setName("Random Integers with some missing");
// Start here with the current table . . .
lastN = 30; // Number of non-missing values to retain
dt = CurrentDataTable();
vals = dt << getAsMatrix;
// Loop over columns . . .
newVals = [];
for(c=1, c<=NCol(vals), c++,
NMV = vals[LocNonMissing(vals[0, c]), c]; // Non-mising values in this column
if(NRow(NMV) >= lastN, // Do we have enough non-missing values?
lastNMV = NMV[(NRow(NMV) - lastN + 1)::NRow(NMV)]; // If so, get the 'lastN' of these . . .
newVals = newVals||lastNMV; // . . . and add them into a new column
);
);
dt2 = AsTable(newVals);
dt2 << setName("Last "||Char(lastN)||" non-missing Random Integers");Betreff: Letzte 30 Teile für jede Zeile und die anderen Daten löschenProbieren Sie diese Version aus.
Names Default to Here( 1 );
// create the example
dt = New Table( "Odd Lengths",
New Column( "Column 1", Numeric, Continuous, Values( 1::50 ) ),
New Column( "Column 2", Numeric, Continuous, Values( 1::75 ) ),
New Column( "Column 3", Numeric, Continuous, Values( 1::28 ) )
);
Wait( 0 );
// process the data table
For( col = N Col( dt ), col > 0, col--,
values = Column( dt, col ) << Get Values;
not missing = Sum( Not( Is Missing( values ) ) );
If( not missing < 30,
dt << Delete Columns( Column( dt, col ) ),
end = Contains( values, . ) - 1;
If( end == -1, end = N Row( dt ) );
view = end - 29 :: end;
Column( dt, col ) << Set Values( values[view] );
);
);
dt << Select Where( Row() > 30 ) << Delete Rows;
Betreff: Letzte 30 Teile für jede Zeile und die anderen Daten löschen@Mark_Bailey Das funktioniert großartig! Mir ist klar geworden, dass ich Daten in Spalten mit weniger als 30 und mehr als 30 habe. Gibt es eine einfache Möglichkeit, nur diese anzuzeigen? Ein Beispiel Spalte 1 hat 50 Zeilen und Spalte 2 hat 75 Zeilen und Spalte 3 hat 28 Zeilen und ich möchte, dass jede Zeile in den letzten 30 Zeilen keine Informationen enthält, die unter 30 liegen. Wenn sie also 29 oder weniger Datenpunkte hat, würde ich sie gerne löschen Auch. Danke für die Hilfe!
Betreff: Letzte 30 Teile für jede Zeile und die anderen Daten löschenHier ist eine weitere Version, mit der Sie das gleiche Ergebnis wie mit der zweiten Lösung erzielen können @txnelson
For( col = 1, col <= N Col( dt ), col++,
values = Column( dt, col ) << Get Values;
end = Contains( values, . ) - 1;
If( end == -1, end = N Row( dt ) );
view = end - 29 :: end;
Column( dt, col ) << Set Values( values[view] );
);
dt << Select Where( Row() > 30 ) << Delete Rows;
Betreff: Letzte 30 Teile für jede Zeile und die anderen Daten löschenDas Löschen aller Zeilen bis auf die letzten 30 in einer Datentabelle ist einfach.
Names Default To Here( 1 );
dt = Current Data Table();
dt << select where( Row() > N Rows( dt ) - 30 );
dt << delete rows;
Wenn Sie die letzten 30 nicht fehlenden Datenpunkte für jede Spalte finden und diese dann als Ihre n Spalten mal 30 Datenzeilen speichern möchten, ist das etwas schwieriger und ich werde die Gültigkeit dieser Vorgehensweise in Frage stellen.Das Ergebnis wäre, dass praktisch jede Beziehung zwischen Datenpunkten zwischen den verschiedenen Spalten entfernt würde.
Names Default To Here( 1 );
dt = Current Data Table();
// Copy the data table retaining no rows;
dtCopy = dt << subset( selected rows( 0 ), selected columns( 0 ) );
dtCopy << select where( Row() >= 0 );
dtCopy << delete rows;
For( i = 1, i <= N Cols( dtCopy ), i++,
theList = {};
For( k = N Rows( dt ), k >= 1, k--,
If( Is Missing( Column( dt, i )[k] ) == 0,
Insert Into( theList, Column( dt, i )[k] );
If( N Items( theList ) >= 30,
Break()
);
)
);
Column( dtCopy, i ) << set values( Reverse( theList ) );
);