Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Alors voici ce que j'espère :
Lorsque vous cliquez sur « Ajuster tout » dans la plateforme de distribution, vous obtenez de nombreux ajustements

Cependant, si l'AICc du meilleur ajustement est à moins de 5 de la distribution normale, vous pouvez tout aussi bien utiliser l'ajustement normal. Alors, s'il y avait un moyen de créer un script qui passerait en revue un tas de colonnes pour lesquelles le meilleur ajustement a déjà été exécuté, puis ajusterait l'ajustement sélectionné (en supposant qu'il ne soit pas normal) à Normal s'il se situe dans un AICc de 5 par rapport à la distribution normale ? Un point bonus serait de pouvoir disposer d'une zone de saisie pour saisir le delta de l'AICc avec lequel vous êtes prêt à vivre. Le double bonus serait de supprimer les t de Students, Cauchy et ExGaussian des options de sélection, car vous ne pouvez pas calculer les capacités de processus sur ces distributions (et ce sera la prochaine étape à exécuter après l'exécution de ce script de nettoyage).
J'ai essayé et je n'arrive pas à le faire fonctionner, toute aide serait grandement appréciée !!
Steve
Automatisation et scriptsRe : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?
s'il existe un moyen de créer un script qui passerait en revue un tas de colonnes qui ont déjà eu le meilleur ajustement exécuté
La plateforme de distribution est-elle toujours ouverte et contient-elle tous les résultats ou où sont stockés les résultats ? Faut-il laisser les distributions de comparaison ouvertes ou suffit-il qu'une seule distribution ait été adaptée ?
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Salut @jthi !
Oui, la plateforme serait toujours ouverte et toutes les comparaisons de meilleurs ajustements seraient toujours là. Je pense que idéalement, la boîte de comparaison serait toujours là, mais je peux vivre avec seulement le meilleur ajustement si c'est beaucoup plus facile.
Alors, commençons ici

et pour quelque chose comme ça, normal serait choisi, mais disons que Normal était tout en bas de la liste, alors SHASH serait choisi

Ici, la valeur normale serait choisie car elle se situe dans les 5 valeurs de l'AICc de Johnson Sb.

J'espère que cela vous aidera et merci d'avoir regardé ceci !
Steve
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Il y a deux choses difficiles avec cela qui sont liées : vous ne pouvez pas trier par défaut les cases du tableau avec JSL (à ma connaissance et cela pose des problèmes sur de nombreuses plateformes) et cela rend difficile la définition correcte des cases à cocher (elles ne sont pas dans le même ordre que les autres valeurs, il est fort probable qu'elles ne soient pas toujours triées ou quelque chose comme ça)
Et à cause de cela, je ne suis pas sûr que cela fonctionnera dans tous les cas (j'ai essayé de me passer du For mais les commandes ont trop changé)
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Cities.jmp");
dt << Distribution(
Continuous Distribution(Column(:"pop- m"n), Process Capability(0)),
Continuous Distribution(Column(:POP), Process Capability(0)),
Continuous Distribution(Column(:Max deg. F Jan), Process Capability(0)),
Continuous Distribution(Column(:OZONE), Process Capability(0)),
Continuous Distribution(Column(:CO), Process Capability(0)),
Continuous Distribution(Column(:SO2), Process Capability(0)),
Continuous Distribution(Column(:NO), Process Capability(0)),
Continuous Distribution(Column(:PM10), Process Capability(0)),
Continuous Distribution(Column(:Lead), Process Capability(0)),
Continuous Distribution(Column(:X), Process Capability(0)),
Continuous Distribution(Column(:Y), Process Capability(0)),
Fit All
);
// Script basically starts from here
Names Default To Here(1);
obs = Current Report() << XPath("//OutlineBox[@helpKey='Distrib']");
If(N Items(obs) > 0,
dist = obs[1] << Get Scriptable Object;
);
obs = Report(dist) << XPath("//OutlineBox[text()='Compare Distributions']");
For Each({ob}, obs,
tb = ob[TableBox(1)];
vals = tb << get;
// Order might be incorrect in these
dists = vals["Distribution"];
normal_idx = Contains(dists, "Normal");
normal_aic = vals["AICc"][normal_idx];
m_aic = Matrix(vals["AICc"]);
// This comparison might require some fixes
ifs = (ob << parent) << XPath("//IfBox");
Remove From(ifs, 1, 2); // might require more robust method
fit_titles = (ifs << child) << get title;
If(Min(m_aic) >= normal_aic - 20 & normal_idx > 1,
For(i = 1, i <= N Items(dists), i++,
tb[1] << Set All(0);
tb[1] << Set(i);
idx = Contains(ifs << get, 1);
If(fit_titles[idx] == "Fitted Normal Distribution",
break();
);
);
);
);
Write();
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Merci pour le script @jthi !
J'ai essayé de l'exécuter et j'ai eu cette erreur

Extrait du journal :
/*:
Plage d'indices dans l'accès ou l'évaluation de 'fit_titles[ /*###*/idx]' , fit_titles[/*###*/idx]
à la ligne 54 dans C:\Users\steve.hampton\OneDrive - Precision Castparts Corp\Documents\Script 3.jsl
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Vous devez commencer à ajouter des impressions de débogage et vérifier où cela se passe mal. Vous devrez peut-être modifier la boucle de N Items(dists) à N Items(fit_titles) ou quelque chose du genre.
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?J'ai essayé d'aborder la solution de manière similaire à celle de Jarmo, mais différemment. Différent dans la mesure où j'ai choisi d'utiliser les cases à cocher dans la zone de tableau sous la zone de comparaison des distributions. J'ai raisonné (correctement) que si l'AICc normal était à 5 de la distribution réellement sélectionnée, alors tout ce qui doit être fait dans le JSL est de décocher la case pour la distribution choisie par JMP et de cocher la case pour la distribution normale. Si dans le JSL, cette désélection et cette sélection sont effectuées, la distribution correcte est affichée sur l'histogramme. Cependant, il semble que les messages normaux qui sont utilisés pour manipuler une case à cocher dans le JSL ne renvoient pas ou ne définissent pas correctement les cases à cocher... à moins que je n'aie pas une compréhension complète des cases à cocher affichées dans une case de tableau.
Voir ci-dessous ce que j'ai trouvé
names default to here(1);
dt =
// Open Data Table: semiconductor capability.jmp
// → Data Table( "semiconductor capability" )
Open( "$SAMPLE_DATA/semiconductor capability.jmp" );
dist = dt << Distribution(
Continuous Distribution(
Column( :INM2 ),
Process Capability(0),
fit all(1)
)
);
// From the current report, find all of the Compare Distribution boxes
//dist =( current report() << xpath( "//OutlineBox[text()='Compare Distributions']" ));
// There is a bug in JMP where the check boxes return a standard order, not the order displayed
checkBoxOrder = {
"Normal",
"Cauchy",
"Student's t",
"Lognormal",
"Exponential",
"Gamma",
"Johnson Sb",
"SHASH",
"ExGaussian",
"Normal 2 Mixture",
"Normal 3 Mixture",
"Weibull"
};
distr = dist<<REPORT></REPORT>
<P>J'espère que quelqu'un pourra m'éclairer sur mon erreur de logique ou d'utilisation. Si aucun éclaircissement de ce type n'est disponible, je transmettrai cette question au support JMP.</P>Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Je suppose que les cases à cocher ne sont pas vraiment liées à la boîte de tableau -> lorsque vous triez la boîte de tableau, les cases à cocher ne sont pas triées correctement. Et puis, par défaut, la boîte de tableau est déjà triée d'une manière différente de "par défaut". Vous vous retrouvez donc dans une situation très étrange où vous n'avez aucune idée de l'index qui définit quel élément car ils ne sont pas alignés. C'est pourquoi j'ai opté pour la boucle For très compliquée et pour vérifier quelle boîte Ifbox de distribution était activée.
Si vous utilisez l'ordre « par défaut » (que vous ne pouvez pas définir avec JSL, ce qui entraîne également des problèmes sur d'autres plates-formes, comme le filtrage des processus), vous obtenez ceci

ce sont les indices « corrects » le plus souvent .
Je n'ai pas encore essayé si vous pouviez calculer quel index est lequel étant donné l'ordre de tri actuel (ou en sachant quelle colonne a été utilisée pour le tri).
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Salut @jthi ,
Merci encore d'avoir tenté le coup (et @txnelson ) ! J'ai joué avec le code et il fonctionne plutôt bien la plupart du temps. Comme il semble que le problème soit la façon dont les distributions de comparaison se comportent avec l'ordre, je pense que si je ne me soucie pas d'avoir toutes les distributions toujours là, quelque chose comme ceci devrait fonctionner : exécutez la plate-forme de distribution et ajustez-les toutes, puis créez une table de données combinée des sorties de distribution de comparaison, dans la nouvelle table, supprimez les trois distributions qui ne peuvent pas être utilisées pour une capacité de processus, puis effectuez la comparaison sur les distributions pour l'AICc de l'ajustement supérieur par rapport à l'endroit où se trouve la normale, puis prenez l'ajustement supérieur ou l'ajustement normal pour chaque variable et supprimez tout le reste (faisant ainsi de cette table une table de propriétés de distributions), puis utilisez la plate-forme de gestion des limites pour appliquer ces distributions en tant que propriété de colonne sur la table principale et enfin relancez la plate-forme de distribution. J'espère essayer ce week-end et voir si cela fonctionnerait.
Steve
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?C'était mon idée originale et c'est pourquoi j'ai demandé si vous vouliez conserver les distributions de comparaison, alors j'ai opté pour cette option. Tant que vous pouvez conserver les mêmes noms entre les différentes plateformes, cela devrait fonctionner correctement.
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Ok, j'y suis arrivé ! Je suis sûr que ce n'est pas très éloquent mais je voulais le dire au cas où cela pourrait aider quelqu'un d'autre.
La première étape consiste à sélectionner les colonnes de votre table de données pour lesquelles vous souhaitez ajuster les distributions.
//rev 8-24-24
names default to here(1);
dt=current data table();
colnames=dt<<GET selected="" columns=""> expr(var1),
1
)
)
)
)));
dt1<< New Column( "Column 14 2",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula(
If( Is Missing( Col Maximum( :Column 13, :Y ) ) & :Column 10 == 2,
1
)
),
Set Selected
);
dt1 << New Column( "Column 14",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Sum( :Column 12, :Column 13,:Column 14 2 ) ),
Set Selected
);
wait(0);
// Delete column formula: Column 10
dt1:Column 10 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 11 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 12 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 13 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 14 << Delete Formula;
//Delete non-Normal fits that are wihtin our criteria
// Delete selected rows
dt1 << Select Where( :Column 14 == 1 ) <<
Invert Row Selection << Delete Rows;
//Puts all the Y's and distributiosn into lists
col={};
dist={};
for each row(dt1,
insertinto(col,:Y);
insertinto(dist,:Distribution);
);
close(dt1, nosave);
//bring back up the distribution platform but only with the Y's that we could fit a distribution to
rpt=new window("Best Distribution",
obj=dt<<DISTRIBUTION></DISTRIBUTION></GET>Thanks for the inspiration <A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/14366" target="_blank">@jthi</A> and <A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/2687" target="_blank">@txnelson</A> (I used a bunch of your other posts to help me get here)
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Bon travail.
J'ai parcouru votre script et j'ai apporté quelques modifications.
- J'ai modifié la syntaxe de création de la colonne 10 pour qu'elle soit identique à la syntaxe utilisée pour les colonnes, Colonne 11 - Colonne 14. Je vous suggère de modifier les noms que vous utilisez. Les noms actuels, Colonne 10, etc., sont un nom que JMP utilise lorsqu'il crée des colonnes et nécessite un nom de colonne par défaut. Par conséquent, il y a de fortes chances qu'une table de données sur laquelle vous allez exécuter votre script ait une colonne portant l'un des noms que vous utilisez. Je vous suggère de simplement remplacer la colonne 10, etc. par _Colonne 10_, etc. pour éviter le problème.
- J'ai modifié votre code de nouvelle colonne en spécifiant une formule pour utiliser Définir chaque valeur. Il fournit la même fonctionnalité, mais sans créer de formule, que votre code finit par devoir supprimer.
- J'ai supprimé une ligne For Each que vous utilisez pour créer les listes, col et Dist. Cela peut être fait en une seule instruction, éliminant ainsi le besoin de parcourir la table de données
- Je vous suggère également de mettre une vérification au début de votre code pour déterminer s'il y a réellement des colonnes sélectionnées, et si ce n'est pas le cas, d'afficher un message indiquant à l'utilisateur de sélectionner des colonnes et d'exécuter à nouveau le script.
Voir mes modifications ci-dessous
//rev 8-24-24
names default to here(1);
dt=current data table();
colnames=dt<<GET selected="" columns=""> expr(var1),
1
)
)
)
)));
dt1<< New Column( "Column 14 2",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Each Value( //Formula(
If( Is Missing( Col Maximum( :Column 13, :Y ) ) & :Column 10 == 2,
1
)
),
Set Selected
);
dt1 << New Column( "Column 14",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Each Value( //Formula(
Sum( :Column 12, :Column 13,:Column 14 2 ) ),
Set Selected
);
wait(0);
/*
// Delete column formula: Column 10
dt1:Column 10 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 11 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 12 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 13 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 14 << Delete Formula;*/
//Delete non-Normal fits that are wihtin our criteria
// Delete selected rows
/*dt1 << Select Where( :Column 14 == 1 ) <<
Invert Row Selection << Delete Rows;*/
dt1 << delete rows( dt1 << get rows where( :Column 14 != 1) );
//Puts all the Y's and distributiosn into lists
/*col={};
dist={};
for each row(dt1,
insertinto(col,:Y);
insertinto(dist,:Distribution);
);*/
col = dt1:Y << get values;
dist = dt1:Distribution << get values;
close(dt1, nosave);
//bring back up the distribution platform but only with the Y's that we could fit a distribution to
rpt=new window("Best Distribution",
obj=dt<<DISTRIBUTION></DISTRIBUTION></GET>
<P> </P>
<P> </P>Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Merci @txnelson !
Ces changements ont été formidables et m'ont aidé à en apprendre encore plus. J'apprécie énormément votre temps et votre aide !
Steve
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?
Voici mon approche basée sur votre script
Names Default To Here(1);
/*
dt = Open("$SAMPLE_DATA/Cities.jmp");
*/
NON_VALID_DIST = {"Cauchy", "ExGaussian", "Student's t"};
If(N Table() == 0,
Throw("No tables open");
);
dt = Current Data Table();
colnames = dt << Get selected Columns(continuous, "string");
If(N Items(colnames) == 0,
Throw("No continuous columns selected");
);
nw = New Window("What AICc is comparable?", Show Menu(0), Show Toolbars(0), <<MODAL> 1, // Normal isn't the only distribution
If(dt_fits[yrows[2], "AICc"] - same_limit <= dt_fits[yrows[1], "AICc"],
aa_y[ycol] = "Normal";
,
aa_y[ycol] = dt_fits[yrows[1], "Distribution"];
);
,
aa_y[ycol] = "Normal";
);
);
Close(dt_fits, No save);
dist = dt << Distribution(
Column(Eval(aa_y << get keys)),
Process Capability(0),
Invisible
);
For Each({{col, best_dist}, idx}, aa_y,
Eval(Substitute(
Expr(dist[idx] << _fit_),
Expr(_fit_), Parse("Fit " || best_dist); // I hate using Evil Parse, but in this case it might work as long as you "fix" Johnson fits
));
);
dist << Show Window(1);
Caption(Remove);
Write();</MODAL>
J'envisagerais également de créer la première distribution pour les meilleurs ajustements une colonne à la fois. De cette façon, vous pouvez mettre à jour la légende après chaque colonne, car le calcul du meilleur ajustement peut prendre beaucoup de temps (vous pouvez également envisager de mettre à jour la barre de progression).
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Merci @jthi , il y a beaucoup de bonnes choses à apprendre ici aussi ! J'apprécie toute l'aide !
Steve
Re : Cela peut être une demande importante, mais quelqu'un peut-il aider avec un script pour essayer de sélectionner une distribution normale lorsqu'elle est assez proche de la distribution la mieux ajustée ?Vous pouvez également remplacer vos multiples instructions if par if-elseif OU par Match. Je ne les ai pas testés, mais cela devrait vous donner une idée.
Avec plusieurs instructions if comme vous en avez, il les vérifiera toujours toutes, mais une seule doit correspondre. Si vous utilisez if-elseif, il s'arrêtera à la première correspondance trouvée ( If() )
For(i = 1, i <= N Items(col), i++,
If(
dist[i] == "Normal", obj[i]<< Fit Normal,
dist[i] == "Exponential", obj[i]<< Fit Exponential,
dist[i] == "Gamma", obj[i]<< Fit Gamma,
dist[i] == "Johnson Su", obj[i]<< Fit Johnson,
dist[i] == "Lognormal", obj[i]<< Fit Lognormal,
dist[i] == "Normal 2 Mixture", obj[i]<<FIT normal="" 2="" mixture=""></FIT>
<P> </P>
<P> </P>
<P>Et <A href="https://www.jmp.com/support/help/en/18.0/#page/jmp/match-function.shtml#ww246655" target="_blank" rel="noopener noreferrer">Match()</A> devrait être généralement plus facile à lire et si je me souviens bien, il est également légèrement plus rapide</P>
<P> </P>
<CODE class=" language-jsl">For(i = 1, i <= N Items(col), i++,
Match(dist[i],
"Normal", obj[i]<< Fit Normal,
"Exponential", obj[i]<< Fit Exponential,
"Gamma", obj[i]<< Fit Gamma,
"Johnson Su", obj[i]<< Fit Johnson,
"Lognormal", obj[i]<< Fit Lognormal,
"Normal 2 Mixture", obj[i]<<FIT normal="" 2="" mixture=""></FIT>
<P> </P>
<P> </P>