Das ist vielleicht eine große Herausforderung, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Ich hoffe also auf Folgendes:
Wenn Sie auf „Alles anpassen“ in der Distributionsplattform klicken, erhalten Sie viele Anpassungen

Wenn der AICc der besten Anpassung jedoch innerhalb von 5 der Normalverteilung liegt, können Sie auch die normale Anpassung verwenden. Also, wenn es eine Möglichkeit gibt, ein Skript zu erstellen, das eine Reihe von Spalten durchgeht, für die bereits die beste Anpassung ausgeführt wurde, und dann die ausgewählte Anpassung (vorausgesetzt, sie ist nicht normal) auf Normal anpasst, wenn sie innerhalb eines AICc von 5 zur Normalverteilung liegt? Bonuspunkte gäbe es für die Möglichkeit, ein Eingabefeld zu haben, in das Sie das Delta des AICc eingeben können, mit dem Sie leben möchten. Ein doppelter Bonus wäre, Students t, Cauchy und ExGaussian aus den Auswahloptionen zu entfernen, da Sie die Prozessfähigkeiten für diese Verteilungen nicht berechnen können (und dies wird der nächste Schritt sein, der ausgeführt wird, nachdem dieses Bereinigungsskript ausgeführt wurde).
Ich habe es versucht und kriege es nicht zum Laufen. Ich wäre für jede Hilfe sehr dankbar!!
Steve
Automatisierung und SkriptingBetreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?
wenn es eine Möglichkeit gibt, ein Skript zu erstellen, das eine Reihe von Spalten durchgeht, für die bereits die beste Anpassung durchgeführt wurde
Ist die Verteilungsplattform noch geöffnet und enthält sie alle Ergebnisse oder wo sind die Ergebnisse gespeichert? Müssen Sie die Vergleichsverteilungen geöffnet lassen oder reicht es aus, dass eine Verteilung angepasst wurde?
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Hey @jthi !
Ja, die Plattform wäre immer noch offen und alle Vergleiche mit der besten Passform wären immer noch da. Ich denke, im Idealfall wäre das Vergleichsfeld immer noch da, aber ich kann mit der besten Passform leben, wenn das viel einfacher ist.
Beginnen wir also hier

und für so etwas wie diese Passform würde normal gewählt werden, aber nehmen wir an, dass Normal ganz unten auf der Liste steht, dann würde SHASH gewählt werden

Hier würde „normal“ gewählt, da es innerhalb von 5 des AICc-Werts von Johnson Sb liegt.

Ich hoffe, das hilft, und danke, dass Sie sich das angesehen haben!
Steve
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Damit sind zwei Schwierigkeiten verbunden, die miteinander in Zusammenhang stehen: Sie können das Tabellenfeld mit JSL nicht standardmäßig sortieren (soweit ich weiß, verursacht dies auf vielen Plattformen Probleme) und dies erschwert die korrekte Einstellung der Kontrollkästchen (sie sind nicht in derselben Reihenfolge, in der Sie andere Werte sehen, höchstwahrscheinlich werden sie nicht immer sortiert oder so etwas).
Und deshalb bin ich mir nicht sicher, ob das in jedem Fall funktioniert (ich habe versucht, auf das For zu verzichten, aber die Reihenfolge hat sich zu sehr geändert)
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();
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Danke für das Skript, @jthi !
Ich habe versucht, es auszuführen und habe diesen Fehler erhalten

Aus dem Protokoll:
/*:
Indexbereich beim Zugriff oder bei der Auswertung von 'fit_titles[ /*###*/idx]' , fit_titles[/*###*/idx]
in Zeile 54 in C:\Benutzer\steve.hampton\OneDrive - Precision Castparts Corp\Dokumente\Script 3.jsl
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Sie müssen mit dem Hinzufügen von Debug-Ausdrucken beginnen und prüfen, wo es schief geht. Möglicherweise müssen Sie die Schleife von N Items(dists) in N Items(fit_titles) oder so etwas ändern.
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Ich habe versucht, eine Lösung zu finden, die Jarmo ähnelt, aber anders ist. Der Unterschied besteht darin, dass ich die Kontrollkästchen im Tabellenfeld unter dem Feld „Verteilungsübersicht vergleichen“ verwendet habe. Ich habe (korrekterweise) angenommen, dass, wenn der normale AICc innerhalb von 5 der tatsächlich ausgewählten Verteilung liegt, in JSL nur das Kontrollkästchen für die in JMP ausgewählte Verteilung deaktiviert und das Kontrollkästchen für die Normalverteilung aktiviert werden muss. Wenn diese Deaktivierung und Aktivierung in JSL vorgenommen wird, wird die richtige Verteilung im Histogramm angezeigt. Es scheint jedoch, dass die normalen Nachrichten, die zum Bearbeiten eines Kontrollkästchens innerhalb von JSL verwendet werden, Kontrollkästchen nicht richtig zurückgeben oder festlegen … es sei denn, ich verstehe die in einem Tabellenfeld angezeigten Kontrollkästchen nicht vollständig.
Unten finden Sie meine Erkenntnisse
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>Ich hoffe, dass mir jemand einen Hinweis auf meinen Logik- oder Verwendungsfehler geben kann. Wenn keine Aufklärung möglich ist, werde ich dies an den JMP-Support weiterleiten.</P>Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Ich vermute, dass die Kontrollkästchen nicht wirklich an das Tabellenfeld gebunden sind -> wenn Sie das Tabellenfeld sortieren, werden die Kontrollkästchen nicht richtig sortiert. Und dann ist das Tabellenfeld standardmäßig bereits anders sortiert als „Standard“. Sie landen also in einer sehr seltsamen Situation, in der Sie keine Ahnung haben, welcher Index welches Element festlegt, da sie nicht ausgerichtet sind. Deshalb habe ich mich für die sehr komplizierte For-Schleife entschieden und geprüft, welche Ifbox der Distribution aktiviert war.
Wenn Sie die „Standard“-Reihenfolge verwenden (die Sie mit JSL nicht festlegen können, was auch auf anderen Plattformen, wie z. B. bei Prozessüberprüfungen, zu Problemen führt), erhalten Sie Folgendes

Dies sind meistens die „richtigen“ Indizes.
Ich habe noch nicht ausprobiert, ob man bei der aktuellen Sortierreihenfolge (oder mit dem Wissen, welche Spalte zum Sortieren verwendet wurde) berechnen könnte, welcher Index welcher ist.
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Hallo @jthi ,
Nochmals vielen Dank, dass Sie sich daran versucht haben (und @txnelson )! Ich habe mit dem Code herumgespielt und er funktioniert die meiste Zeit ziemlich gut. Da das Problem anscheinend darin liegt, wie sich die Vergleichsverteilungen bei der Sortierung verhalten, denke ich, dass, wenn es mir egal ist, ob alle Verteilungen noch da sind, so etwas funktionieren sollte: Führen Sie die Verteilungsplattform aus und passen Sie alles an, erstellen Sie dann eine kombinierte Datentabelle der Vergleichsverteilungsausgaben, entfernen Sie in der neuen Tabelle die drei Verteilungen, die nicht für eine Prozessfähigkeit verwendet werden können, führen Sie dann den Vergleich der Verteilungen für den AICc der besten Anpassung mit dem Bereich durch, in dem die Normalverteilung landet, nehmen Sie dann die beste Anpassung oder die Normalverteilung für jede Variable und löschen Sie den Rest (und machen Sie diese Tabelle so zu einer Verteilungseigenschaftstabelle), verwenden Sie dann die Plattform zur Verwaltung von Grenzwerten, um diese Verteilungen als Spalteneigenschaft auf die Haupttabelle anzuwenden, und starten Sie schließlich die Verteilungsplattform neu. Ich hoffe, es dieses Wochenende ausprobieren zu können und zu sehen, ob es funktioniert.
Steve
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Das war meine ursprüngliche Idee und deshalb habe ich gefragt, ob Sie die Vergleichsverteilungen beibehalten möchten, also habe ich mich dafür entschieden. Solange Sie die Namen zwischen verschiedenen Plattformen gleich lassen können, sollte es problemlos funktionieren.
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Okay, ich habe es geschafft! Ich bin sicher, es ist nicht sehr eloquent, aber ich wollte es einfach loswerden, falls es jemandem anderen helfen könnte.
Der erste Schritt besteht darin, die Spalten in Ihrer Datentabelle auszuwählen, für die Sie Verteilungen anpassen möchten.
//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)
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Gute Arbeit.
Ich habe mir Ihr Skript angesehen und einige Änderungen vorgenommen.
- Ich habe die Syntax für die Erstellung von Spalte 10 so geändert, dass sie mit der Syntax für die Spalten 11 bis 14 übereinstimmt. Ich schlage vor, dass Sie die verwendeten Namen ändern. Die aktuellen Namen, Spalte 10 usw., sind Namen, die JMP verwendet, wenn es Spalten erstellt und einen Standardspaltennamen benötigt. Daher besteht eine gute Chance, dass eine Datentabelle, in der Sie Ihr Skript ausführen möchten, eine Spalte mit einem der von Ihnen verwendeten Namen enthält. Mein Vorschlag ist, Spalte 10 usw. einfach in _Spalte 10_ usw. zu ändern, um das Problem zu vermeiden.
- Ich habe Ihren Code für die neue Spalte von der Angabe einer Formel auf die Verwendung von „Jeden Wert festlegen“ geändert. Dies bietet dieselbe Funktionalität, jedoch ohne die Erstellung einer Formel, die Ihr Code letztendlich löschen muss.
- Ich habe ein For Each Row entfernt, das Sie zum Erstellen der Listen, col und Dist verwenden. Dies kann in einzelnen Anweisungen erfolgen, wodurch die Notwendigkeit entfällt, die Datentabelle zu durchlaufen
- Ich schlage außerdem vor, dass Sie am Anfang Ihres Codes eine Prüfung einfügen, um festzustellen, ob tatsächlich Spalten ausgewählt sind. Ist dies nicht der Fall, zeigen Sie eine Meldung an, die den Benutzer auffordert, Spalten auszuwählen und das Skript erneut auszuführen.
Siehe meine Änderungen unten
//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>Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Danke @txnelson !
Diese Änderungen waren großartig und haben mir geholfen, noch mehr zu lernen. Ich weiß Ihre Zeit und Hilfe sehr zu schätzen!
Steve
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?
Hier ist mein Ansatz basierend auf Ihrem Skript
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>
Ich würde auch in Betracht ziehen, die erste Verteilung für die besten Anpassungen spaltenweise zu erstellen. Auf diese Weise könnten Sie die Überschrift nach jeder Spalte aktualisieren, da die Berechnung der besten Anpassung lange dauern kann (Sie könnten auch eine Aktualisierung des Fortschrittsbalkens in Betracht ziehen).
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Danke @jthi , auch hier gibt es viel Gutes zu lernen! Ich bin für jede Hilfe dankbar!
Steve
Betreff: Das ist vielleicht eine große Bitte, aber kann jemand mit einem Skript helfen, um zu versuchen, eine Normalverteilung auszuwählen, wenn sie der am besten angepassten Verteilung ziemlich nahe kommt?Sie können Ihre mehreren if-Anweisungen auch entweder durch if-elseif ODER durch Match ersetzen. Ich habe dies nicht getestet, aber es sollte Ihnen einen Eindruck davon vermitteln.
Bei mehreren if-Anweisungen wie bei Ihnen wird immer nach allen gesucht, aber nur eine sollte übereinstimmen. Wenn Sie if-elseif verwenden, wird es bei der ersten gefundenen Übereinstimmung ( If() ) angehalten.
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>Und <A href="https://www.jmp.com/support/help/en/18.0/#page/jmp/match-function.shtml#ww246655" target="_blank" rel="noopener noreferrer">Match()</A> sollte einfach allgemein leichter zu lesen sein und wenn ich mich recht erinnere, ist es auch etwas schneller</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>