[JSL] Sélectionner des lignes à l'aide de conditions « Complexes »Bonjour à tous,
Je voudrais écrire un script JSL pour sélectionner les lignes d’une table avec des conditions « complexes » :
Je dois sélectionner UNE LIGNE par métrique (colonne : Métrique) avec des conditions PAR ORDRE DE PRIORITÉ :
1- si la condition Flag1 = « FLAG » ET Flag2 = « FLAG » existe, Sélectionner Col Max (:Metric1) de cette condition
2- si la condition Flag1 = « FLAG » XOR Flag2 = « FLAG » existe, Sélectionner Col Max (:Metric1) de cette condition
3- Sinon, sélectionnez la ligne Max (Metric1)
Ci-dessous un code provisoire utilisant For Each Row() et une colonne de débogage, mais ma tentative ne fonctionne pas et n'est pas très élégante.
De plus, je ne sais pas comment effectuer un XOR (OR exclusif) dans JLS sans utiliser une combinaison de portes de base.
Existe-t-il une meilleure façon de procéder ?
Remarque : veuillez trouver ci-joint un PNG illustrant ma demande
Merci
- Prédicateur
Names Default To Here(1);
dt = New Table("RawData",
Add Rows(27),
Compress File When Saved(1),
New Column("Metric",
Character,
"Nominal",
Set Values(
{"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", "D", "D", "D", "D", "D", "D", "D"}
)
),
New Column("Flag1",
Character,
"Nominal",
Set Values(
{"FLAG", "OK", "FLAG", "OK", "OK", "OK", "OK", "FLAG", "FLAG", "OK", "OK", "FLAG", "OK", "OK", "FLAG",
"FLAG", "OK", "OK", "OK", "FLAG", "OK", "OK", "OK", "OK", "OK", "OK", "OK"}
)
),
New Column("Flag2",
Character,
"Nominal",
Set Values(
{"OK", "OK", "OK", "OK", "OK", "FLAG", "OK", "FLAG", "FLAG", "OK", "OK", "FLAG", "OK", "OK", "OK",
"OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK"}
)
),
New Column("metric1",
Numeric,
"Continuous",
Format("Best", 10),
Set Values([1, 2, 3, 5, 7, 10, 13, 2, 4, 5, 6, 8, 11, 1, 2, 4, 5, 5, 9, 12, 1, 2, 4, 5, 5, 9, 18])
)
);
//This attempt doesn't select the right rows
debugcol = dt << New Column("Debug", Numeric, Continuous);
For Each Row(dt,
FLAG_row =
If(
:Flag1 == "FLAG" & :Flag2 == "FLAG",
Col Max(:metric1, :Metric),
IF(
:Flag1 == "FLAG" | :Flag2 == "FLAG",
Col Max(:metric1, :Metric),
If(
:Flag1 == "OK" & :Flag2 == "OK",
Col Max(:metric1, :Metric)
)));
debugcol[Row()] = FLAG_row;
);
dt << select where (:metric1 == :Debug);

Analyse et modélisation de données de baseRe: [JSL] Sélectionner des lignes à l'aide de conditions « Complexes »Voici comment je procéderais

Names Default To Here( 1 );
dt = New Table( "RawData",
Add Rows( 27 ),
Compress File When Saved( 1 ),
New Column( "Metric",
Character,
"Nominal",
Set Values(
{"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", "D", "D",
"D", "D", "D", "D", "D"}
)
),
New Column( "Flag1",
Character,
"Nominal",
Set Values(
{"FLAG", "OK", "FLAG", "OK", "OK", "OK", "OK", "FLAG", "FLAG", "OK", "OK", "FLAG", "OK", "OK", "FLAG", "FLAG",
"OK", "OK", "OK", "FLAG", "OK", "OK", "OK", "OK", "OK", "OK", "OK"}
)
),
New Column( "Flag2",
Character,
"Nominal",
Set Values(
{"OK", "OK", "OK", "OK", "OK", "FLAG", "OK", "FLAG", "FLAG", "OK", "OK", "FLAG", "OK", "OK", "OK", "OK", "OK",
"OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK"}
)
),
New Column( "metric1",
Numeric,
"Continuous",
Format( "Best", 10 ),
Set Values( [1, 2, 3, 5, 7, 10, 13, 2, 4, 5, 6, 8, 11, 1, 2, 4, 5, 5, 9, 12, 1, 2, 4, 5, 5, 9, 12] )
)
);
dt << clear select;
rowsToSelect = {};
groups = associative array(:metric<<GET values=""> 0,
Insert Into( rowsToSelect, Max( theRows ) ),
theRows = dt << get rows where( :metric == group & (:Flag1 == "FLAG" | :Flag2 == "FLAG") );
If( N Rows( theRows ) > 0,
Insert Into( rowsToSelect, Max( theRows ) ),
Insert Into( rowsToSelect, Max( dt << get rows where( :metric == group ) ) )
);
);
);
dt << select rows( rowsToSelect );</GET>Re: [JSL] Sélectionner des lignes à l'aide de conditions « Complexes »Cela peut être fait sans colonnes supplémentaires, mais cela pourrait être plus facile avec elles
Names Default To Here(1);
dt = New Table("RawData",
Add Rows(27),
Compress File When Saved(1),
New Column("Metric",
Character,
"Nominal",
Set Values(
{"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", "D", "D", "D", "D", "D", "D", "D"}
)
),
New Column("Flag1",
Character,
"Nominal",
Set Values(
{"FLAG", "OK", "FLAG", "OK", "OK", "OK", "OK", "FLAG", "FLAG", "OK", "OK", "FLAG", "OK", "OK", "FLAG", "FLAG", "OK", "OK", "OK", "FLAG",
"OK", "OK", "OK", "OK", "OK", "OK", "OK"}
)
),
New Column("Flag2",
Character,
"Nominal",
Set Values(
{"OK", "OK", "OK", "OK", "OK", "FLAG", "OK", "FLAG", "FLAG", "OK", "OK", "FLAG", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK",
"OK", "OK", "OK", "OK", "OK", "OK"}
)
),
New Column("metric1",
Numeric,
"Continuous",
Format("Best", 10),
Set Values([1, 2, 3, 5, 7, 10, 13, 2, 4, 5, 6, 8, 11, 1, 2, 4, 5, 5, 9, 12, 1, 2, 4, 5, 5, 9, 18])
)
);
typecol = dt << New Column("ROWTYPE", Numeric, Continuous, Formula(
If(:Flag1 == "FLAG" & :Flag2 == "FLAG",
2
, :Flag1 == "OK" & :Flag2 == "OK",
0
,
1
);
));
dt << Select Where(
:metric1 == Col Max(
If(:ROWTYPE == Col Max(:ROWTYPE, :Metric),
:metric1
,
.
),
:Metric
);
);
dt << Delete Columns(typecol);
wait(0);
L'un des problèmes de cette solution est qu'elle pourrait être interrompue dans les prochaines versions de JMP, car vous n'êtes pas censé utiliser autre chose que des références de colonnes avec les fonctions statistiques Col. Voici un élément de la liste de souhaits dans l'espoir que JMP ne rompe pas l'une des « fonctionnalités » les plus utiles dont disposent actuellement ces fonctions
Faire en sorte que l'utilisation d'expressions de formule dans Définir chaque valeur et l'utilisation d'expressions comme premier argument dans les formules statistiques Col soient prises en charge (j'essaie d'utiliser ces fonctions de moins en moins, mais c'est difficile car elles sont actuellement si puissantes et elles créent des scripts plus faciles à lire plus rapidement que d'autres options).
Re: [JSL] Sélectionner des lignes à l'aide de conditions « Complexes »Salut Jim,
Merci pour votre réponse,
Je suis vraiment désolé, je me rends compte que ma demande n'était pas très claire.
Après avoir priorisé le groupe de lignes dans chaque métrique (ce qui fonctionne bien avec votre script),
Je dois sélectionner la ligne de la valeur la plus élevée (colonne : metric1), sans me baser sur Max (theRows) comme dans le script actuel.
Le tableau fictif que j'ai fourni auparavant a ajouté à la confusion car « Col Max (:metric1) » dans chaque groupe est toujours égal à « Max (theRows) ».
Votre script suggéré ne fonctionne plus avec un nouvel ensemble de valeurs. Ci-dessous, j'ai remplacé :metric1 par :Value pour supprimer l'ambiguïté du nom de colonne, et j'ai réorganisé les valeurs numériques.
J'ai essayé de jouer avec "Col Max ()" ajouté comme règle à l'intérieur de "get rows where()", mais sans succès.
(Je me rends compte que mon anglais n'est pas parfait, j'ai donc ajouté une image pour décrire mon objectif, si ma formulation n'est pas assez précise)
Avez-vous une suggestion?
Merci encore
Prédicateur
Names Default To Here( 1 );
dt = New Table( "RawData",
Add Rows( 27 ),
Compress File When Saved( 1 ),
New Column( "Metric",
Character,
"Nominal",
Set Values(
{"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", "D", "D",
"D", "D", "D", "D", "D"}
)
),
New Column( "Flag1",
Character,
"Nominal",
Set Values(
{"FLAG", "OK", "FLAG", "OK", "OK", "OK", "OK", "FLAG", "FLAG", "OK", "OK", "FLAG", "OK", "OK", "FLAG", "FLAG",
"OK", "OK", "OK", "FLAG", "OK", "OK", "OK", "OK", "OK", "OK", "OK"}
)
),
New Column( "Flag2",
Character,
"Nominal",
Set Values(
{"OK", "OK", "OK", "OK", "OK", "FLAG", "OK", "FLAG", "FLAG", "FLAG", "OK", "FLAG", "OK", "OK", "OK", "OK", "OK",
"OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK", "OK"}
)
),
New Column( "Value",
Numeric,
"Continuous",
Format( "Best", 10 ),
Set Values( [1, 2, 9, 5, 13, 2, 7, 9, 4, 11, 6, 8, 3, 1, 2, 13, 5, 5, 9, 12, 1, 2, 4, 5, 5, 9, 7] )
)
);
dt << clear select;
rowsToSelect = {};
groups = associative array(:metric<<GET values=""> 0,
Insert Into( rowsToSelect, Max( theRows ) ),
theRows = dt << get rows where( :metric == group & (:Flag1 == "FLAG" | :Flag2 == "FLAG") /*& :Value == Col Max (:Value, :Metric, :Flag1, :Flag2)*/ );
show (theRows);
If( N Rows( theRows ) > 0,
Insert Into( rowsToSelect, Max( theRows ) ),
Insert Into( rowsToSelect, Max( dt << get rows where( :metric == group /*& :Value == Col Max (:Value, :Metric, :Flag1, :Flag2)*/) ) );
show (theRows);
);
);
);
dt << select rows( rowsToSelect );</GET>
Re: [JSL] Sélectionner des lignes à l'aide de conditions « Complexes »Jarmo,
Merci beaucoup,
La solution que vous proposez fonctionne dans mon script principal !
Bien que vous ayez mentionné qu'une future version de JMP pourrait briser cet arrangement de fonctions Col.
Dans mon entreprise, nous mettons toujours à jour la version JMP vers la dernière version chaque année.
J'utiliserai votre script pour le moment et j'essaierai d'obtenir l'aide de Jim (txnelson) pour faire fonctionner sa suggestion afin que mon code soit plus robuste.
Merci encore!!
Prédicateur
Re: [JSL] Sélectionner des lignes à l'aide de conditions « Complexes »Nous ne savons pas si JMP va changer de comportement. JMP considère qu'il s'agit d'un comportement non intentionnel, ce qui signifie qu'il est susceptible d'être modifié à tout moment sans aucune information. Félicitations à l'élément de la liste de souhaits, si vous ne l'avez pas encore fait, pour transformer cela en une fonctionnalité plutôt qu'un comportement non intentionnel ( Make using formula expressions in Set Each Value et using expressions as first argument in Col statistical formulas taken behavior )
Re: [JSL] Sélectionner des lignes à l'aide de conditions « Complexes »Je viens de le faire,
Merci:)