Hola, necesito ayuda para limpiar algunos datos. Los datos de la tabla contienen varios ID, fechas y categorías. Estoy interesado en identificaciones con categoría 1 y 2, o 1 y 2 y 3, o 1 y 3, conservando solo las entradas con la fecha máxima para cada categoría. ¿Podría proporcionarnos el mejor script para esta solución? ¡Gracias!
| IDENTIFICACIÓN | categoría | fecha | costoA | costoB | costoC | costoD |
| 1 | 1 | 21/01/16 | 5000 | 0 | 3000 | 500 |
| 1 | 1 | 21/01/16 | 1000 | 5000 | 10000 | 0 |
| 1 | 1 | 21/01/16 | 20000 | 0 | 10 | 50 |
| 1 | 2 | 22/01/16 | 3000 | 0 | 0 | 50000 |
| 1 | 3 | 2/1/16 | 1 | 10 | 900 | 0 |
| 2 | 1 | 2/04/13 | 0 | 100 | 10000 | 5000 |
| 2 | 2 | 3/04/13 | 0 | 0 | 0 | 642,49 |
| 2 | 1 | 2/04/13 | 1 | 10 | 900 | 0 |
| 3 | 2 | 6/03/15 | 50 | 0 | 0 | 259,58 |
Aquí hay un pequeño script que debería funcionar. Encuentra las filas que cumplen con su definición. Luego, esas filas se subdividen en una nueva tabla.
Names Default To Here( 1 );
dt = Current Data Table();
For Each Row(
If( :date == Col Maximum( :date, :ID ),
currID = :ID;
//currID="1"
cats = Associative Array( dt:category[dt << get rows where( :ID == currID )] ) << get keys;
If( cats[1] == "1" & Length( cats ) > 1,
dt << select rows( Row() )
);
)
);
dtNew = dt << subset( selected columns(0), selected rows(1),
output table("Final")
);
// The above code will allow multiple rows within a given ID, when there are
// multiple rows with the same maximum date. Run the below code to
// get rid of the multiple entries, if that is what is desired
dtNew << select duplicate rows(Match(:ID));
dtNew << delete rows;


Si se ejecutan las últimas 2 líneas del script anterior, las filas de ID duplicadas se eliminan.

ello Jim,
Gracias por su ayuda. Me disculpo por cualquier confusión. Necesito cada ID que debe tener categoría 1 y 2 y/o 3 en la mesa final. Si hay ID repetidos con la misma categoría, necesito la fila que tiene la fecha máxima. La tabla debe proporcionarse aquí. De forma anticipada, muchas gracias por su ayuda.
| IDENTIFICACIÓN | categoría | fecha | costoA | costoB | costoC | costoD |
| 1 | 1 | 21/01/16 | 20000 | 0 | 10 | 50 |
| 1 | 2 | 22/01/16 | 3000 | 0 | 0 | 50000 |
| 2 | 1 | 2/04/13 | 0 | 100 | 10000 | 5000 |
| 2 | 2 | 3/04/13 | 0 | 0 | 0 | 642,49 |
| 3 | 1 | 6/03/15 | 3000 | 0 | 0 | 817 |
| 3 | 2 | 6/03/15 | 50 | 0 | 0 | 259,58 |
| 4 | 1 | 6/03/15 | 10000 | 0 | 0 | 710.16 |
| 4 | 2 | 6/03/15 | 5000 | 0 | 0 | 1087 |
| 4 | 3 | 16/03/15 | 0 | 0 | 0 | 326,7 |
Mi ejemplo anterior tenía Categoría como columna de caracteres. Tu ejemplo es numérico. También cambié la lógica para asegurar que haya al menos las categorías 1 y 2, 1 y 3 o 1 y 2 y 3.
Names Default To Here( 1 );
dt = Current Data Table();
For Each Row(
If( :date == Col Maximum( :date, :ID ),
currID = :ID;
cats = Associative Array( dt:category[dt << get rows where( :ID == currID )] ) << get keys;
show(cats);
If( Length( cats ) > 1,
If( cats[1] == 1 & (cats[2] == 2 | cats[2] == 3),
dt << select rows( Row() )
)
);
)
);
dtNew = dt << subset( selected columns( 0 ), selected rows( 1 ), output table( "Final" ) );
Aquí hay una forma de abordar esto usando funciones Col
Names Default To Here(1);
dt = New Table("Untitled 3",
Add Rows(11),
Compress File When Saved(1),
New Column("ID", Numeric, "Continuous", Format("Best", 12), Set Values([1, 1, 1, 2, 3, 3, 4, 4, 4, 4, 4])),
New Column("Category", Character, "Nominal", Set Values({"A", "A", "B", "A", "A", "C", "A", "A", "B", "B", "C"})),
New Column("Date", Numeric, "Continuous", Format("Best", 12), Set Values([1, 1, 2, 1, 1, 2, 1, 2, 1, 2, 1]))
);
dt << New Column("KEEP", Numeric, Nominal, Formula(
Col Sum(Row() == Col Min(Row(), :category, :id), :id) > 1 & :date == Col Max(:date, :category, :id)
));
Cambie la fórmula a << Seleccionar dónde / << Obtener filas dónde o úsela con un subconjunto para tomar las filas que desea conservar.

Editar:
La versión original no tuvo en cuenta que podría faltar la categoría 1 (esto supone que la categoría es una columna numérica)
New Column("KEEP", Numeric, Nominal, Formula(
Col Sum(Row() == Col Min(Row(), :category, :id), :id) > 1
& :date == Col Max(:date, :category, :id)
& Col Sum(If(:category == 1, 1, .), :id)
));