Salve, avrei bisogno di assistenza per ripulire alcuni dati. I dati nella tabella contengono più ID, date e categorie. Sono interessato agli ID con categoria 1 e 2, oppure 1 e 2 e 3, oppure 1 e 3, conservando solo le iscrizioni con la data massima per ciascuna categoria. Potresti fornire lo script migliore per questa soluzione? Grazie!
| ID | categoria | data | costoA | costoB | costoC | costo D |
| 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/4/13 | 0 | 100 | 10000 | 5000 |
| 2 | 2 | 4/3/13 | 0 | 0 | 0 | 642.49 |
| 2 | 1 | 2/4/13 | 1 | 10 | 900 | 0 |
| 3 | 2 | 6/3/15 | 50 | 0 | 0 | 259,58 |
Ecco un piccolo script che dovrebbe funzionare. Trova le righe che soddisfano la tua definizione. Tali righe vengono quindi inserite in un sottoinsieme in una nuova tabella.
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;


Se vengono eseguite le ultime 2 righe dello script precedente, le righe ID duplicate vengono eliminate.

Jim,
Grazie per l'aiuto. Mi scuso per qualsiasi confusione. Ho bisogno di ogni ID che deve avere la categoria 1 e 2 e/o 3 nel tavolo finale. Se sono presenti ID ripetuti con la stessa categoria, ho bisogno della riga con la data massima. La tabella dovrebbe essere fornita qui. Grazie in anticipo per il tuo aiuto.
| ID | categoria | data | 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/4/13 | 0 | 100 | 10000 | 5000 |
| 2 | 2 | 4/3/13 | 0 | 0 | 0 | 642.49 |
| 3 | 1 | 6/3/15 | 3000 | 0 | 0 | 817 |
| 3 | 2 | 6/3/15 | 50 | 0 | 0 | 259,58 |
| 4 | 1 | 6/3/15 | 10000 | 0 | 0 | 710.16 |
| 4 | 2 | 6/3/15 | 5000 | 0 | 0 | 1087 |
| 4 | 3 | 16/3/15 | 0 | 0 | 0 | 326.7 |
Il mio esempio sopra aveva Categoria come colonna di caratteri. Il tuo esempio è numerico. Ho anche cambiato la logica per garantire che ci siano almeno le categorie 1&2, 1&3 o 1&2&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" ) );
Ecco un modo in cui potresti affrontare questo problema utilizzando le funzioni 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)
));
Modifica la formula in << Seleziona dove / << Ottieni righe dove oppure utilizzala con un sottoinsieme per prendere le righe che vuoi conservare.

Modificare:
La versione originale non teneva conto del fatto che la categoria 1 poteva mancare (ciò presuppone che la categoria sia una colonna numerica)
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)
));