Últimas 30 piezas por cada fila y borra los demás datosHola, todos,
Tengo una tabla de datos que tiene varias columnas y cada columna tiene una cantidad diferente de filas con datos. Estoy tratando de encontrar una manera de obtener las últimas 30 filas de datos en cada columna. Por ejemplo, la columna 1 tiene 50 filas y la columna 2 tiene 75 filas y quiero que cada fila tenga las últimas 30 filas de información. ¿Hay un script que pueda hacer eso?
Tabla de datossecuencias de comandosRe: Últimas 30 piezas de cada fila y borra los demás datosPara los futuros lectores de esta pista, una corrección a @Mark_Bailey La declaración sobre su código en comparación con el segundo fragmento de código de la respuesta de @txnelson debe aclararse.Los dos fragmentos de código producirán los mismos resultados si se asume que una vez que se encuentra un valor faltante, no aparecen valores adicionales no faltantes en la columna.@Mark_Bailey el código requiere que exista la cantidad mínima de valores que no faltan, donde el código @txnelson no
Re: Últimas 30 piezas de cada fila y borra los demás datosFWIW, aquí hay otra versión que usa matrices:
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");Re: Últimas 30 piezas de cada fila y borra los demás datosPrueba esta versión.
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;
Re: Últimas 30 piezas de cada fila y borra los demás datos@Mark_Bailey ¡Esto funciona muy bien! Me he dado cuenta de que tengo datos en columnas que son menores a 30 y mayores a 30. ¿Hay una manera fácil de mostrar solo esto? Un ejemplo la columna 1 tiene 50 filas y la columna 2 tiene 75 filas y la columna 3 tiene 28 filas y quiero que cada fila tenga las últimas 30 filas de información, nada que esté por debajo de 30, así que si tiene 29 o menos puntos de datos, me gustaría eliminarlo además. ¡Gracias por la ayuda!
Re: Últimas 30 piezas de cada fila y borra los demás datosAquí hay otra versión para lograr el mismo resultado que la segunda solución de @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;
Re: Últimas 30 piezas de cada fila y borra los demás datosEliminar todas menos las últimas 30 filas en una tabla de datos es fácil.
Names Default To Here( 1 );
dt = Current Data Table();
dt << select where( Row() > N Rows( dt ) - 30 );
dt << delete rows;
Si está solicitando encontrar los últimos 30 puntos de datos que no faltan para cada columna, y luego guardarlos como sus n columnas por 30 filas de datos, eso es un poco más difícil y cuestionaré la validez de hacerlo.El resultado de eso sería eliminar prácticamente cualquier relación entre los puntos de datos entre las diferentes columnas.
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 ) );
);