Bonjour à tous,
J'essaie de créer une formule ou un script qui définira une certaine valeur ("Bon", "Mauvais" ou "N/A") pour chaque ligne en fonction s'il y a une autre ligne dans le tableau avec des valeurs correspondant à la logique qui utilise la ligne actuelle comme entrée.
J'ai un script qui fait exactement cela en utilisant des boucles For imbriquées lors de l'utilisation d'un petit sous-ensemble de la table de données complète. Cependant, avec la table de données complète que j'essaie d'utiliser, qui compte environ 1 million de lignes, le script plante simplement JMP.
Existe-t-il un moyen plus efficace de permettre à JMP d'effectuer cela ? (Ou si cela peut être fait avec SQL, je peux le faire avant de l'introduire dans JMP).
Voir ci-joint le script qui fait ce dont je parle.
Il n'est généralement pas nécessaire d'imbriquer des boucles for lorsque vous travaillez avec des tables de données.
Pourriez-vous fournir un petit sous-ensemble de vos données et inclure une colonne contenant les résultats souhaités ?
D'accord, je vais simuler les données pour des raisons de confidentialité.
| Cola | colB | colC | datecol | colE | Logique |
| A0001 | 16 | 100 | 01/04/2022 09:15:01 | Action1 | N / A |
| A0001 | 100 | 182 | 01/04/2022 09:15:31 | Action2 | Bien |
| A0001 | 100 | 100 | 01/04/2022 09:15:36 | Action1 | N / A |
| A0002 | 212 | 200 | 02/04/2022 03:15:21 | Action1 | N / A |
| A0002 | 211 | 282 | 02/04/2022 03:15:11 | Action2 | Mauvais |
| A0002 | 212 | 200 | 02/04/2022 03:15:16 | Action1 | N / A |
| A0003 | 441 | 382 | 01/05/2022 01:15:31 | Action2 | Mauvais |
| A0004 | 441 | 382 | 01/05/2022 05:16:31 | Action2 | Mauvais |
| A0004 | 441 | 300 | 01/05/2022 05:15:31 | Action1 | N / A |
Si la logique du script d'origine n'était pas claire :
Si le colE de la ligne actuelle est "Action 1": alors affectez "N/A" ;
Sinon, si le colE de la ligne actuelle est "Action 2", alors suivez la logique du paragraphe suivant.
S'il existe une autre ligne dans la table avec les mêmes valeurs de la ligne actuelle pour les colonnes colA et colB ; la valeur colC de la ligne actuelle est exactement 82 de plus que cette autre ligne ; les valeurs colDate sont à moins de 18 secondes l'une de l'autre ; le colE de la ligne actuelle est "Action 2" et le colE de cette autre ligne est "Action 1": puis affectez "Bon" ; sinon attribuez "Mauvais".
Appréciez toute aide ! Je ne vois tout simplement pas de moyen sans boucles imbriquées pour le moment.
Mais je réalise maintenant au moins que je devrais mettre un Break () après la ligne 25 de mon script original. Aucune raison de continuer à chercher une autre ligne qui correspond à mes critères si j'en ai déjà trouvé au moins une.
La logique dans ce script est trop compliquée car je ne connais pas toutes les limitations des données (peut-il y avoir par exemple plusieurs correspondances) et je ne l'ai pas optimisé
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");
