Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?Así que esto es lo que espero:
Cuando haces clic en Ajustar todo en la plataforma de distribución, obtienes muchos ajustes.

Sin embargo, si el AICc del mejor ajuste está dentro de 5 de la distribución normal, también podría usar el ajuste normal. Entonces, ¿si hubiera una manera de crear un script que pasara por un montón de columnas que ya tuvieron el mejor ajuste ejecutado y luego ajustara el ajuste seleccionado (asumiendo que no es normal) a Normal si está dentro de un AICc de 5 con respecto a la distribución normal? Los puntos adicionales serían poder tener un cuadro de entrada para ingresar el delta del AICc con el que está dispuesto a vivir. La doble ventaja sería eliminar la t de Student, Cauchy y ExGaussian de las opciones de selección, ya que no puede calcular las capacidades del proceso en estas distribuciones (y ese será el siguiente paso a ejecutar después de que se ejecute este script de limpieza).
Lo he intentado y no puedo hacerlo funcionar. ¡Cualquier ayuda sería muy apreciada!
Steve
Automatización y scriptingRe: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?
Si hubiera una manera de crear un script que pudiera recorrer un montón de columnas que ya tenían el mejor ajuste ejecutado
¿La plataforma de distribución sigue abierta y tiene todos los resultados o dónde se almacenan los resultados? ¿Es necesario dejar abiertas las distribuciones de comparación o basta con que se haya ajustado una distribución?
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?¡Hola @jthi !
Sí, la plataforma seguiría abierta y todas las comparaciones de las mejores opciones seguirían estando ahí. Creo que lo ideal sería que el cuadro de comparación siguiera ahí, pero puedo vivir solo con la mejor opción si eso es mucho más fácil.
Así que empezando por aquí

y para algo como esto, se elegiría normal, sin embargo, digamos que Normal estuviera muy abajo en la lista, entonces se elegiría SHASH

Aquí se elegiría el valor normal ya que está dentro de 5 del valor AICc de Johnson Sb.

¡Espero que esto ayude y gracias por mirar esto!
Steve
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?Hay dos cosas difíciles con esto que están relacionadas: no se puede ordenar la tabla de forma predeterminada con JSL (hasta donde yo sé y esto causa problemas en muchas plataformas) y esto dificulta configurar las casillas de verificación correctamente (no están en el mismo orden que ves otros valores, lo más probable es que no siempre se ordenen o algo así)
Y debido a esto, no estoy seguro de si esto funcionará en todos los casos (intenté prescindir del For pero los órdenes cambiaron demasiado)
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: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?¡Gracias por el guión @jthi !
Intenté ejecutarlo y obtuve este error.

Del registro:
/*:
Rango de subíndices en el acceso o evaluación de 'fit_titles[ /*###*/idx]', fit_titles[/*###*/idx]
en la línea 54 en C:\Users\steve.hampton\OneDrive - Precision Castparts Corp\Documents\Script 3.jsl
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?Debes comenzar a agregar impresiones de depuración y verificar dónde falla. Es posible que tengas que cambiar el bucle de N Items(dists) a N Items(fit_titles) o algo así.
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?Intenté abordar la solución de manera similar a la de Jarmo, pero diferente. La diferencia es que elegí usar las casillas de verificación en el cuadro de tabla debajo del cuadro de esquema de comparación de distribuciones. Razoné (correctamente) que si el AICc normal estaba dentro de los 5 de la distribución seleccionada real, entonces todo lo que se necesita hacer en JSL es desmarcar la casilla de verificación para la distribución elegida de JMP y seleccionar la casilla de verificación para la distribución normal. Si en JSL se realiza esta desmarcación y selección, se muestra la distribución correcta en el histograma. Sin embargo, parece que los mensajes normales que se usan para manipular una casilla de verificación desde JSL no devuelven o configuran las casillas de verificación correctamente... a menos que no comprenda completamente las casillas de verificación que se muestran en un cuadro de tabla.
Vea a continuación lo que encontré.
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>Espero que alguien pueda indicarme cuál es mi error de lógica o de uso. Si no hay ninguna explicación al respecto, le pasaré el asunto al soporte técnico de JMP.</P>Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?Supongo que las casillas de verificación no están realmente vinculadas al cuadro de la tabla -> cuando ordenas el cuadro de la tabla, las casillas de verificación no se ordenan correctamente. Y luego, de forma predeterminada, el cuadro de la tabla ya está ordenado de una manera diferente a la "predeterminada". Por lo tanto, terminas en una situación muy extraña en la que no tienes idea de qué índice establece qué elemento, ya que no están alineados. Es por eso que opté por el bucle For muy complicado y para verificar qué cuadro If de la distribución estaba habilitado.
Si usa el orden "predeterminado" (que no puede configurar con JSL, lo que también causa problemas en otras plataformas, como la revisión de procesos), obtendrá esto

Estos son los índices "correctos" más frecuentemente .
Aún no he probado si se puede calcular qué índice es cuál dado el orden de clasificación actual (o sabiendo qué columna se utilizó para ordenar).
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?Hola @jthi ,
Gracias de nuevo por intentarlo (y a @txnelson ). He estado jugando con el código y funciona bastante bien la mayor parte del tiempo. Dado que parece que el problema es la forma en que se comporta Comparar distribuciones con el ordenamiento, creo que si no me importa tener todas las distribuciones todavía allí, algo como esto debería funcionar: Ejecute la plataforma de distribución y ajuste todo, luego haga una tabla de datos combinada de las salidas de distribución de comparación, en la nueva tabla elimine las tres distribuciones que no se pueden usar para una capacidad de proceso, luego haga la comparación en las distribuciones para el AICc del ajuste superior vs donde aterriza lo normal, luego tome el ajuste superior o el ajuste normal para cada variable y elimine todo el resto (haciendo así que esta tabla sea una tabla de propiedades de distribuciones), luego use la plataforma de administración de límites para aplicar esas distribuciones como una propiedad de columna en la tabla principal y finalmente reinicie la plataforma de distribución. Espero intentarlo este fin de semana y ver si funciona.
Steve
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?Esa era mi idea original y por eso pregunté si querías conservar la función Comparar distribuciones, así que me decidí. Siempre que puedas mantener los mismos nombres en distintas plataformas, debería funcionar bien.
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?¡Bien, ya lo he conseguido! Seguro que no es muy elocuente, pero quería dejarlo ahí por si acaso le sirve a alguien más.
El primer paso es seleccionar las columnas de la tabla de datos en las que desea ajustar distribuciones.
//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: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?Buen trabajo.
Revisé tu guión y realicé algunos cambios.
- Cambié la sintaxis de la creación de la Columna 10 para que sea la misma que la sintaxis utilizada para la columna, Columna 11 - Columna 14. Le sugiero que cambie los nombres que está utilizando. Los nombres actuales, Columna 10, etc., son nombres que JMP utiliza cuando crea columnas y necesita un nombre de columna predeterminado. Por lo tanto, existe una buena posibilidad de que una tabla de datos en la que va a ejecutar su secuencia de comandos pueda tener una columna con uno de los nombres que está utilizando. Mi sugerencia es simplemente cambiar Columna 10, etc. a _Columna 10_, etc. para evitar el problema.
- Cambié el código de la columna Nueva para que no especifique una fórmula y use Establecer cada valor. Proporciona la misma funcionalidad, pero sin crear una fórmula, que el código termina eliminando.
- Eliminé un For Each Row que estabas usando para crear las listas col y Dist. Esto se puede hacer en instrucciones individuales, eliminando así la necesidad de recorrer la tabla de datos.
- También te sugiero que coloques una verificación al comienzo de tu código para determinar si realmente hay columnas seleccionadas y, si no, mostrar un mensaje indicándole al usuario que seleccione columnas y ejecute el script nuevamente.
Vea mis cambios a continuación
//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: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?¡Gracias @txnelson !
Esos cambios fueron geniales y me ayudaron a aprender aún más. ¡Agradezco mucho su tiempo y ayuda!
Steve
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?
Aquí está mi enfoque basado en tu guión.
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>
También consideraría crear la primera distribución para obtener los mejores ajustes, una columna a la vez. De esta manera, podría actualizar el título después de cada columna, ya que calcular el mejor ajuste puede llevar mucho tiempo (también podría considerar actualizar la barra de progreso).
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?Gracias @jthi , ¡aquí también hay muchas cosas interesantes para aprender! ¡Agradezco toda tu ayuda!
Steve
Re: Puede que sea mucho pedir, pero ¿puede alguien ayudar con un script para intentar seleccionar una distribución normal cuando está bastante cerca de la distribución mejor ajustada?También puedes reemplazar tus múltiples sentencias if con if-elseif o con Match. No he probado estas, pero deberían darte una idea.
Con múltiples sentencias if como la suya, siempre se comprobarán todas, pero solo una debería coincidir. Si utiliza if-elseif, se detendrá en la primera coincidencia encontrada ( 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>Y <A href="https://www.jmp.com/support/help/en/18.0/#page/jmp/match-function.shtml#ww246655" target="_blank" rel="noopener noreferrer">Match()</A> debería ser más fácil de leer en general y, si recuerdo correctamente, también es un poco más rápido.</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>