Ciao a chiunque,
Sto cercando di creare una formula o uno script che imposterà un determinato valore ("Buono", "Cattivo" o "N/D") per ogni riga in base alla presenza di un'altra riga nella tabella con valori che corrispondono alla logica che utilizza la riga corrente come input.
Ho uno script che fa proprio questo utilizzando cicli For nidificati quando si utilizza un piccolo sottoinsieme dell'intero datatable. Tuttavia, con il datatable completo che sto cercando di utilizzare, che è di circa 1 milione di righe, lo script blocca semplicemente JMP.
Esiste un modo più efficiente per consentire a JMP di eseguire questa operazione? (Oppure, se è possibile farlo con SQL, posso farlo prima di inserirlo in JMP).
Vedi allegato per lo script che fa ciò di cui sto parlando.
Di solito non è necessario nidificare i cicli quando si lavora con le tabelle di dati.
Potresti fornire un piccolo sottoinsieme dei tuoi dati e includere una colonna con i risultati desiderati?
Ok, prenderò in giro i dati per motivi di privacy.
| Coca Cola | colB | colC | colDate | colE | Logica |
| A0001 | 16 | 100 | 01/04/2022 9:15:01 | Azione1 | N / A |
| A0001 | 100 | 182 | 01/04/2022 9:15:31 | Azione2 | Bene |
| A0001 | 100 | 100 | 01/04/2022 9:15:36 | Azione1 | N / A |
| A0002 | 212 | 200 | 02/04/2022 03:15:21 | Azione1 | N / A |
| A0002 | 211 | 282 | 02/04/2022 03:15:11 | Azione2 | Cattivo |
| A0002 | 212 | 200 | 02/04/2022 03:15:16 | Azione1 | N / A |
| A0003 | 441 | 382 | 01/05/2022 1:15:31 | Azione2 | Cattivo |
| A0004 | 441 | 382 | 01/05/2022 05:16:31 | Azione2 | Cattivo |
| A0004 | 441 | 300 | 01/05/2022 05:15:31 | Azione1 | N / A |
Se la logica dello script originale non era chiara:
Se il colE della riga corrente è "Azione 1": allora assegna "N/A";
Altrimenti, se il colE della riga corrente è "Azione 2", segui la logica nel paragrafo successivo.
Se esiste un'altra riga nella tabella con gli stessi valori della riga corrente per le colonne colA e colB; il valore colC della riga corrente è esattamente 82 in più rispetto a quest'altra riga; i valori colDate sono entro 18 secondi l'uno dall'altro; il colE della riga corrente è "Azione 2" e il colE di quest'altra riga è "Azione 1": quindi assegna "Buono"; altrimenti assegna "Cattivo".
Apprezzo qualsiasi aiuto! Al momento non vedo un modo senza loop nidificati.
Ma ora almeno mi rendo conto che dovrei inserire un Break() dopo la riga 25 del mio script originale. Non c'è motivo di continuare a cercare un'altra riga che corrisponda ai miei criteri se ne ho già trovata almeno una esistente.
La logica in questo script è eccessivamente complicata in quanto non conosco tutte le limitazioni dei dati (ad esempio possono esserci più corrispondenze) e non l'ho ottimizzato
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(9),
Compress File When Saved(1),
New Column("colA", Character, "Nominal", Set Values({"A0001", "A0001", "A0001", "A0002", "A0002", "A0002", "A0003", "A0004", "A0004"})),
New Column("colB", Numeric, "Continuous", Format("Best", 9), Set Values([16, 100, 100, 212, 211, 212, 441, 441, 441])),
New Column("colC", Numeric, "Continuous", Format("Best", 9), Set Values([100, 182, 100, 200, 282, 200, 382, 382, 300])),
New Column("colDate",
Character(22),
"Nominal",
Set Values(
{" 2022/04/01 9:15:01 AM", " 2022/04/01 9:15:31 AM", " 2022/04/01 9:15:36 AM", " 2022/04/02 3:15:21 AM", " 2022/04/02 3:15:11 AM",
" 2022/04/02 3:15:16 AM", " 2022/05/01 1:15:31 AM", " 2022/05/01 5:16:31 AM", " 2022/05/01 5:15:31 AM"}
)
),
New Column("colE",
Character(16),
"Nominal",
Set Values({"Action1", "Action2", "Action1", "Action1", "Action2", "Action1", "Action2", "Action2", "Action1"})
),
New Column(" Logic", Character(16), "Nominal", Set Values({" N/A", " Good", " N/A", " N/A", " Bad", " N/A", " Bad", " Bad", " N/A"}))
);
dt << New Column("Group", Character, Nominal, << Set Each Value(char(:colA)||char(:colB)));
//fix date
Column(dt, "colDate") << Set Each Value(Substitute(:colDate, " AM", "")) << Data Type(Numeric);
dt << New Column("Logic", Character, Nominal, << Set Each Value(
As Constant(
m_group = :Group << get values;
m_c = :colC << get values;
m_date = :colDate << get values;
);
If(:colE == "Action1",
"N/A";
, :colE == "Action2",
cur_group_idx = Loc(m_group, :Group);
If(N Items(cur_group_idx) == 0,
"Bad"
,
plus_idx = cur_group_idx[Loc(:colC - 82 == m_c[cur_group_idx])];
If(N Items(plus_idx) == 0,
"Bad"
,
timediff_idx = Loc(Abs(m_date[plus_idx] - :colDate) <= 18);
If(N Items(timediff_idx) > 0,
If(:colE == "Action2" & :colE[timediff_idx[1]] == "Action1",
"Good"
,
"Bad"
)
,
"Bad"
);
)
);
,
"Bad";
);
));
dt << Delete Column("Group");
