Hola,
Tengo que administrar archivos de big data a diario (10.000 columnas x 20.000 filas).
Mi objetivo es obtener estadísticas de capacidad de todas las columnas con límites, utilizando el método de mejor ajuste (solo unas pocas columnas se distribuyen normalmente).
He hecho un script rápido y sucio que:
- recorrer columnas con límites,
- distribución de la trama > "se adapta a todos" > capacidad,
- recoge la información en la ventana del informe y
- cerrar la ventana del informe
El código "parece" funcionar, pero cuando trazo las métricas individualmente para verificar si la nueva tabla coincide con la información, a veces los resultados difieren (no son el mismo tipo de distribución, no son los mismos valores Ppk/Cpk). Por otro lado, USL, LSL y N siempre tienen razón (por lo que el script selecciona la información de la ventana derecha)
No se de donde viene el problema:
- Agregué algunos comandos Wait() para asegurarme de que el procesador pueda ponerse al día antes de iniciar un nuevo ciclo (pero, ¿es suficiente? ¿Es la forma correcta?)
- ¿Es porque la función JMP Fits all no es tan precisa como esperaba?
- ¿Es algo más?
Adjunté un script que genera una tabla con 15k filas y fórmulas aleatorias, seguidas del código real.
En este ejemplo, el primero debería ser SHASH pero informa Johnson Sl en la tabla (con capacidad diferente). los 2x otros son similares.
Muchas gracias por tu ayuda 
Predicador
//Create table with random distribution
dt = New Table( "tabletest",
Add Rows( 15000 ),
New Column( "Normal 10,1", Numeric, "Continuous", formula( Random Normal( 10, 1 ) ) ),
New Column( "LogNormal 10,1", Numeric, "Continuous", formula( Random Lognormal( 10, 1 ) ) ),
New Column( "Gamma 10,1", Numeric, "Continuous", formula( Random Gamma( 10, 1 ) ) ),
New Column( "Normal 10,2", Numeric, "Continuous", formula( Random Normal( 10, 2 ) ) );
);
Column( dt, "Normal 10,1" ) << set property( "spec limits", {LSL( 6 ), USL( 14 ), Show Limits( 0 )} );
Column( dt, "LogNormal 10,1" ) << set property( "spec limits", {LSL( 0 ), USL( 400000 ), Show Limits( 0 )} );
Column( dt, "Gamma 10,1" ) << set property( "spec limits", {LSL( 0 ), USL( 40 ), Show Limits( 0 )} );
dt << save( "$Desktop\tabletest.jmp" );
//Get Column only with limits (At east LSL or USL, I don't care about target)
MetricCols = dt << Get Column Names( numeric, continuous );
Show( MetricCols );
For( i = N Items( MetricCols ), i >= 1, i--,
Q = Column( MetricCols[i] ) << Get Property( "Spec limits" );
Show( Q );
spec_x = Eval List( {Arg( Q, 1 )/*, Arg( Q, 2 ), Arg( Q, 3 )*/} );
Show( spec_x );
If( N Row( Loc( spec_x, Empty() ) ),
Remove From( MetricCols, i )
);
);
//Create a new table to collect the stats from the "Test" table
CpkTable = New Table( "Capability Best Fit",
Add Rows( N Items( MetricCols ) ),
New Column( "Metric", "Character", "Nominal" ),
New Column( "N", "Numeric", "Continuous" ),
New Column( "LSL", "Numeric", "Continuous" ),
New Column( "USL", "Numeric", "Continuous" ),
New Column( "Best Fit", "Character", "Nominal" ),
New Column( "Cpk", "Numeric", "Continuous" ),
New Column( "Cpl", "Numeric", "Continuous" ),
New Column( "Cpu", "Numeric", "Continuous" )
);
//Loop to run Distribution > Fit ALL > Capability and collect the stats
For( i = 1, i <= N Items( MetricCols ), i++,
Show( i );
dt = Open( "$Desktop\tabletest.jmp" );
dis = dt << Distribution(
Continuous Distribution( Column( As Column( MetricCols[i] ) ), Fit Distribution( "All" ), Process Capability( 0 ), invisible )
);
Wait( 0 );
// Point to the first capability analysis and create a data table from it
dtCpk = dis << report;
Wait( 0 );
// Fill USL and LSL in the new table
Limits = Column( MetricCols[i] ) << Get Property( "Spec limits" );
Try( CpkTable:LSL[i] = Limits["LSL"] );
Try( CpkTable:USL[i] = Limits["USL"] );
// Find N and fill the new table
Try(
FindN = dtCpk["Summary Statistics"][Number Col Box( 1 )] << get;
CpkTable:N[i] = FindN[6];
);
// find the best fit and fill the new table
Try(
var = dtCpk["Compare Distributions"][String Col Box( "Distribution" )] << get;
CpkTable:Best Fit[i] = var[1];
CpkTable:Metric[i] = Char( MetricCols[i] );
);
// get CPK parameters from best fit capability analysis and fill the new table
Try(
cpk = dtCpk["Fitted " || var[1]]["Quantile Sigma"][Number Col Box( "Index" )] << get;
CpkTable:Cpk[i] = cpk[2];
CpkTable:Cpl[i] = cpk[4];
CpkTable:Cpu[i] = cpk[5];
Show( MetricCols[i] );
Show( var[1] );
Show( cpk );
);
Wait( 0 );
dtCpk << close window;
);Pude replicar el problema. Lo reduje a un problema con la especificación "Ajustar distribución ("Todos")" dentro del comando Distribución. Parece que mover la "Distribución de ajuste" a una llamada separada soluciona la discrepancia.
dis = dt << Distribution(
Continuous Distribution( Column( As Column( MetricCols[i] ) )/*, Fit Distribution( "All" ), Process Capability( 0 )*/, invisible )
);
dis << Fit All;
Le sugiero que entregue este tema al grupo de apoyo de JMP.
Gracias Jim,
De hecho, la solución funciona y ahora muestra el ajuste correcto en la nueva tabla.
Me comunicaré con el grupo de soporte de JMP.
¿Existe una forma inteligente en JSL de generar la capacidad del proceso para lograr el mejor ajuste desde ese punto? (Para poder completar la nueva tabla con Cpk, Cpu...)
Podría pensar en una forma sucia de hacerlo (encontrar el ajuste, cerrar el informe, volver a abrir el informe con la capacidad del ajuste correcto), pero si hay una forma más inteligente de hacerlo, preferiría.
Probé algunas variaciones del código siguiente, no funciona y no pude encontrar nada en el índice de secuencias de comandos ni en las discusiones.
Gracias de antemano,
Predicador
dis = dt << Distribution(
Continuous Distribution( Column( As Column( MetricCols[i] ) ),/*, Fit Distribution( "All" ),*/ Process Capability( 0 ), invisible )
);
dis << Fit All;
dis << Process Capability ("Lognormal");