Formule permettant de vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneJMP pour Mac
Version 17.2.0 (701896)
J'ai une colonne « Données » avec des lignes de nombre_nombre comme ceci :
1_3
3_7
6_5
...
Je souhaite tester cette colonne pour voir si certaines lignes contiennent des valeurs provenant d'une liste de valeurs, puis marquer ou étiqueter les lignes qui le font.
Je sais que je pourrais construire une formule élaborée comme celle-ci :
If( :Die X_Y == "3_9" | :Die X_Y == "3_4",
1,
0
)
Mais c'est très laborieux pour de longues listes de valeurs différentes à vérifier. J'aimerais simplement pouvoir coller une liste de valeurs à vérifier dans une formule, délimitée par un espace ou une virgule.
J'ai trouvé la fonction « Contient un élément ». Elle fonctionne bien pour un élément, mais l'entrée d'aide n'offre aucune indication sur la manière de construire l'option « liste ». J'ai essayé ceci (en spécifiant le délimiteur facultatif comme un espace) :
If( Contains Item( :Die X_Y, "3_4 3_9", " " ),
"exclude",
"not exclude"
)
et ceci:
If( Contains Item( :Data, "3_4,3_9", "," ),
"exclude",
"not exclude"
)
Je comprends que le délimiteur par défaut est une virgule, mais je voulais l'appliquer pour trouver quelque chose qui fonctionne. Aucune des fonctions Contains Item ne renvoie le comportement recherché (1 logique s'il y a une correspondance, 0 sinon). S'il existe une meilleure fonction à utiliser, veuillez nous en informer.
Il s’agit d’un problème généralisé que j’aimerais pouvoir résoudre : inspecter une colonne pour trouver des correspondances avec de longues listes d’éléments.
Merci
Automatisation et scriptsmacOSRe : Formule permettant de vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneUn effet secondaire agréable :
Cette discussion m'a fait réfléchir :
Est-ce que Contient augmente également la vitesse des agrégations Col.. ?
Et croyez-le ou non, c'est le cas. Waouh, c'est le cas !!!!
https://community.jmp.com/t5/Discussions/Comment-utiliser-la-formule-Col-Maximum-avec-un-quot-où-quot/mp/810363/highlight/true#M99287
Une idée de la raison pour laquelle la comparaison des personnages est si lente ?
Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonnela lecture est : 3 arguments
- x - une chaîne de caractères
- 3 options :
- élément à rechercher
- une liste de plusieurs éléments - l'un d'entre eux correspond-il
- un modèle à rechercher - argument optionnel : le délimiteur pour diviser x en mots
@datanaut a écrit :
Ainsi (selon ma lecture simpliste), soit x, soit la {liste} pourrait contenir les mots à rechercher ou la liste de mots avec lesquels les comparer.
-> oui.
inclus une colonne comme dans l'exemple de Jarmo
Pour une formule en colonne, c'est toujours possible, selon l'idée :
Pour chaque ligne, JMP prendra automatiquement l'entrée de la colonne dans la ligne respective.
Lorsque vous utilisez l'éditeur de formules, vous effectuez cette astuce tout le temps, sans même vous en rendre compte.
Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneMerci à @jthi et @txnelson et @hogi et @mmarchandFSLR pour leurs réponses et leurs efforts à ma question.
Jarmo a trouvé mon problème : changer la liste et l'élément dans ma formule. Merci pour le morceau de code illustrant l'utilisation correcte.
re: "Documentation un peu insuffisante"
Je suis d'accord. Les instructions et l'exemple dans l'index des scripts me semblent un peu ambigus. Voici l'entrée pour l'index des scripts :
"
Contient l'article(x, <article| {liste} |modèle>, <délimiteur>)
...
Returns a Boolean that indicates whether the word (article), one of a list of words (liste), or pattern (modèle) matches one of the words in the text represented by x. Words are delimited by the characters in the optional quoted delimiter (délimiteur) string. A comma is the default delimiter. Blanks are trimmed from the ends of each extracted word from the input text string (x).
"
Ainsi (selon ma lecture simpliste), x ou la {liste} pourrait contenir les mots à rechercher ou la liste de mots avec lesquels les comparer. Quelques exemples supplémentaires montrant des alternatives incluant une colonne comme dans l'exemple de Jarmo pourraient aider à clarifier.
J'ai déjà mis la solution en pratique ! Merci encore.
Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneAh, super !
Au début, j'ai eu une assez mauvaise expérience avec Where() - mais je ne me souviens plus pourquoi.
Peut-être que j'ai utilisé une mauvaise syntaxe - ou le problème a été résolu entre-temps...
Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneJe pense qu'il vaut la peine d'ajouter que la fonction Where() est beaucoup plus rapide (> un ordre de grandeur !) que < <<> Les noms par défaut sont ici( 1 ); dt = Table de données( "SATByYear" ); Afficher( N lignes( dt ) ); //N lignes(dt) = 21245376; maintenant = Heure HP(); dt << Sélectionner Où( :État == "Wisconsin" | :État == "Alabama" ); Attendre( 0 ); total = Heure HP() - maintenant; Imprimer( "<
Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneDésolé, j'ai raté un wait() dans les exécutions précédentes - qui inverse la réponse 1... et conduit à de nouvelles possibilités pour #3, #4 et #5
les nouvelles découvertes :
- Contient l'élément() est plus rapide avec la syntaxe de @jthi - la v2 est plus lente
- Sélectionnez où()devient beaucoup plus rapide en le remplaçant parobtenir les lignes where() + sélectionner les lignes().
- Select Where() devient significativement (!!) plus rapide en remplaçant la comparaison de chaîne par l' élément contient() .
- la combinaison (2) et (3) est assez comparable
- ... également pour des ensembles de données plus volumineux.

Voir plus...
names default to here(1);
dt = Open( "$SAMPLE_DATA/Wafer Stacked.jmp" );
New Column( "x_y",
Character,
Formula( Concat Items( {Char( :X_Die ), Char( :Y_Die )}, "_" ) )
);
wait(0);
t0=hptime();
New Column( "contains item",
Character,
Formula( If( Contains Item( "1_3 3_9", :x_y, " " ), "exclude", "not exclude" ) )
);
dt << run formulas();
t= (hptime()-t0)/1000000;
print("formula - contains item", t);
t0=hptime();
New Column( "contains item v2",
Character,
Formula( If( Contains Item( :x_y, {"3_1","4_4"}) , "exclude", "not exclude" ) )
);
dt << run formulas();
t= (hptime()-t0)/1000000;
print("1) formula - contains item v2", t);
t0=hptime();
New Column( "get rows where",
Character,
set each value("not excluded") );
myrows=[];
for each( {compare}, {"3_1","4_4"},
myrows = V concat to (myrows, dt << get rows where(:x_y == compare));
);
dt << select rows(myrows); // just for fun - it's fast
dt[myrows,"get rows where"] = Repeat({"excluded"},n items(myrows) );
t= (hptime()-t0)/1000000;
print("2) get rows where", t);
t0=hptime();
for each( {compare}, {"3_1","4_4"},
dt<<SELECT where=""> names default to here(1);
dt = Open( "$SAMPLE_DATA/Wafer Stacked.jmp" );
New Column( "x_y",
Character,
Formula( Concat Items( {Char( :X_Die ), Char( :Y_Die )}, "_" ) )
);
wait(0);
t0=hptime();
New Column( "contains item",
Character,
Formula( If( Contains Item( "1_3 3_9", :x_y, " " ), "exclude", "not exclude" ) )
);
dt << run formulas();
t= (hptime()-t0)/1000000;
print("formula - contains item", t);
t0=hptime();
New Column( "contains item v2",
Character,
Formula( If( Contains Item( :x_y, {"3_1","4_4"}) , "exclude", "not exclude" ) )
);
dt << run formulas();
t= (hptime()-t0)/1000000;
print("1) formula - contains item v2", t);
t0=hptime();
New Column( "get rows where",
Character,
set each value("not excluded") );
myrows=[];
for each( {compare}, {"3_1","4_4"},
myrows = V concat to (myrows, dt << get rows where(:x_y == compare));
);
dt << select rows(myrows); // just for fun - it's fast
dt[myrows,"get rows where"] = Repeat({"excluded"},n items(myrows) );
t= (hptime()-t0)/1000000;
print("2) get rows where", t);
t0=hptime();
for each( {compare}, {"3_1","4_4"},
dt<</SELECT> <SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="hogi_0-1731305493836.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="hogi_0-1731305493836.png" style="width: 400px;"><span class="lia-inline-image-display-wrapper" image-alt="hogi_0-1731305493836.png" style="width: 400px;"><img src="https://us.v-cdn.net/6038925/uploads/images/70019i116F7A07829AD82B/hogi_0-1731305493836.png" role="button" title="hogi_0-1731305493836.png" alt="hogi_0-1731305493836.png" /></span></SPAN></SPAN>
Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneajouté à Trucs et astuces - bonnes pratiques avec JMP/JSL
Le n°4 est surprenant. Pour le moment, je dirais :

Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneMerci pour le commentaire.
en creusant plus profondément - en fait, il ne contient pas d'élément par rapport à Sélectionner Où .
quelques constatations :
- Contient l'élément() est plus rapide avec la syntaxe inverse "v2"
- Sélectionnez où()devient beaucoup plus rapide en le remplaçant parobtenir les lignes where() + sélectionner les lignes().
- Select Where() devient beaucoup plus rapide en remplaçant la comparaison de chaîne par l' élément contient() .
- et en combinant (2) et (3) le rend ... facteur 2 plus lent que (2) (?!?!)
- donc, le gagnant (pour cet ensemble de données) est le n°2 :
en tout:

détails:
Voir plus...names default to here(1);
dt = Open( "$SAMPLE_DATA/Wafer Stacked.jmp" );
New Column( "x_y",
Character,
Formula( Concat Items( {Char( :X_Die ), Char( :Y_Die )}, "_" ) )
);
t0=hptime();
New Column( "contains item",
Character,
Formula( If( Contains Item( "1_3 3_9", :x_y, " " ), "exclude", "not exclude" ) )
);
dt << run formulas();
t= (hptime()-t0)/1000000;
print("formula - contains item", t);
t0=hptime();
New Column( "contains item v2",
Character,
Formula( If( Contains Item( :x_y, {"3_1","4_4"}) , "exclude", "not exclude" ) )
);
dt << run formulas();
t= (hptime()-t0)/1000000;
print("1) formula - contains item v2", t);
t0=hptime();
New Column( "get rows where",
Character,
set each value("not excluded") );
myrows=[];
for each( {compare}, {"3_1","4_4"},
myrows = V concat to (myrows, dt << get rows where(:x_y == compare));
);
dt << select rows(myrows); // just for fun - it's fast
dt[myrows,"get rows where"] = Repeat({"excluded"},n items(myrows) );
t= (hptime()-t0)/1000000;
print("2) get rows where", t);
t0=hptime();
for each( {compare}, {"3_1","4_4"},
dt<<SELECT where="">names default to here(1);
dt = Open( "$SAMPLE_DATA/Wafer Stacked.jmp" );
New Column( "x_y",
Character,
Formula( Concat Items( {Char( :X_Die ), Char( :Y_Die )}, "_" ) )
);
t0=hptime();
New Column( "contains item",
Character,
Formula( If( Contains Item( "1_3 3_9", :x_y, " " ), "exclude", "not exclude" ) )
);
dt << run formulas();
t= (hptime()-t0)/1000000;
print("formula - contains item", t);
t0=hptime();
New Column( "contains item v2",
Character,
Formula( If( Contains Item( :x_y, {"3_1","4_4"}) , "exclude", "not exclude" ) )
);
dt << run formulas();
t= (hptime()-t0)/1000000;
print("1) formula - contains item v2", t);
t0=hptime();
New Column( "get rows where",
Character,
set each value("not excluded") );
myrows=[];
for each( {compare}, {"3_1","4_4"},
myrows = V concat to (myrows, dt << get rows where(:x_y == compare));
);
dt << select rows(myrows); // just for fun - it's fast
dt[myrows,"get rows where"] = Repeat({"excluded"},n items(myrows) );
t= (hptime()-t0)/1000000;
print("2) get rows where", t);
t0=hptime();
for each( {compare}, {"3_1","4_4"},
dt<</SELECT>
Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneJ'ai effectué quelques tests de synchronisation en comparant la solution de Jarmo à ma solution, et la solution Contains Item est spectaculairement plus rapide que la solution Select Where.
Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneUsually in cases like this I tend to use Words() to split the string into a list and then compare using Contains() (or in some rare cases Contains Item()). But Contains Item() should also work and you just seem to have your parameters in incorrect order</CODE></P>
<PRE><CODE class=" language-jsl">New Table("Untitled",
Add Rows(3),
Compress File When Saved(1),
New Column("Column 1", Character, "Nominal", Set Values({"1_3", "3_7", "6_5"})),
New Column("Column 2",
Character,
"Nominal",
Formula(
If(Contains Item("1_3 3_9", :Column 1, " "),
"exclude",
"not exclude"
)
),
Set Selected
)
)

Deuxième exemple de Scripting Index


ou la référence de syntaxe JSL ont des exemples intéressants https://www.jmp.com/support/help/en/18.0/#page/jmp/character-functions-2.shtml?os=win&source=application#ww6166335 mais la documentation manque un peu.
Ré: Formule pour vérifier si l'un des éléments d'une liste est contenu dans les lignes d'une colonneVoici l’approche que j’adopterais
names default to here(1);
dt=current data table();
dt << clear select;
find = {"3_1","4_4"};
for each( {compare}, find,
dt<<SELECT where="">
Once the rows are selected, then excluding, deleting etc. can be done.</SELECT>