I currently have a script that creates control and process capability charts for a variety of variables, puts it in a journal, and then saves the journal as a pdf. The problem is, my script is 5000 lines long and runs slower than molasses in a freezer. So I thought it would make more sense to define a function for each type of chart that I build and stitch them together that way. I successfully created functions for the control charts, but I can't get the process capability chart to work.
Here is a script that uses the Airport sample data (attached) to create a chart that looks like the one I'm trying to make:
Process Capability(
Process Variables( :Flight ), // select column for data
Spec Limits( :Flight( LSL( 0 ), /*Target( 30 ),*/ USL( 20 ) ) ), //Spec limits, dont need target
Individual Detail Reports( 1 ),
Capability Box Plots( 0 ),
Goal Plot( 0 ),
Capability Index Plot( 0 ),
Process Performance Plot( 0 ), // hide unnecessary info
{:Flight << Process Capability Analysis(
Overall Sigma Capability( 1 ),
Within Sigma Capability( 1 ),
Histogram( 1, Show Target( 1 ), Show Within Sigma Density( 1 ), Show Overall Sigma Density( 1 ) )
)},
);I would like to define a function with the column name as an input. Here is what I have so far:
capability_chart = function({variable, low, up},
Process Capability(
Process Variables( eval(variable) ), // select column for data
Spec Limits( eval(variable)(LSL( low ), /*Target( 30 ),*/ USL( up )) ),
Individual Detail Reports( 1 ),
Capability Box Plots( 0 ),
Goal Plot( 0 ),
Capability Index Plot( 0 ),
Process Performance Plot( 0 ), // hide unnecessary info
{column(dt, element) << Process Capability Analysis(
Overall Sigma Capability( 1 ),
Within Sigma Capability( 1 ),
Histogram( 1, Show Target( 1 ), Show Within Sigma Density( 1 ), Show Overall Sigma Density( 1 ) )
)}
)
);
capability_chart("Flight", 0, 10)When I run this, a window pops up prompting me for spec limits. I want my script to automatically populate spec limits. I've also tried using column() and ascolumn() instead of eval() in the spec limits line but they did the same thing. Ideally, I wouldn't have to create a spec table or add spec limits as a column property but I can do that if there isn't another way. I also don't want to loop through all the columns and create a bunch of process capability charts because there's an existing format for the report that would be confusing to change. Any help is appreciated.
If you just need Process Capability for one column at the time I would use Distribution Platform in cases like this
Names Default To Here(1);
capability_chart = function({dt, colname, lowlimit, highlimit}, {Default Local},
dist = dt << Distribution(
Continuous Distribution(
Column(:Flight),
Quantiles(0),
Summary Statistics(0),
Histogram(0),
Vertical(0),
Outlier Box Plot(0),
Process Capability(LSL(lowlimit), Target(.), USL(highlimit))
)
);
return(dist);
);
dt = Open("$SAMPLE_DATA/Quality Control/Airport.jmp");
pc = capability_chart(dt, "Flight", 0, 10);
You will end up with a bit different report due to outline boxes, but those can be "hidden" if needed (or just take the Outline Box you are interested in to you report)

Here is a list of tricks to make a JSL expression work:
Expression Handling in JMP: Tipps and Trapdoors
Hints:
- most of the platforms accept the column name (= string, "Flight") in addition the column name (=reference, :Flight)

so the only trick that we need: get the variable replaced by the column name (string).
The problem: for most of the cases Jmp doesn't evaluate an argument before calling the function.So, if you put Eval()around the function argument, it won't help to evaluate it.
-> Wrap everything in an Eval(Eval Expr(()) and replace your Eval()s with Expr()s
... to tell Jmp to evaluate them first.
capability_chart = function({variable, low, up},
Eval Expr(Process Capability(
Process Variables( Expr(variable), // select column for data
Spec Limits( Expr(variable)(LSL( low ), /*Target( 30 ),*/ USL( up )) ),
Individual Detail Reports( 1 ),
Capability Box Plots( 0 ),
Goal Plot( 0 ),
Capability Index Plot( 0 ),
Process Performance Plot( 0 ) // hide unnecessary info
))
));
capability_chart("Flight", 0, 10)
but the Spec Limits("Flight"(LSL( low ), Target( . ), USL( up )) ) doesn't work, it is converted to
Spec Limits( :Flight << {LSL( low ), Target( .), USL( up )} )
So, let's try the trick with Name Expr(As column(column name)):
Spec Limits(Expr(Name Expr(As column(variable)))(LSL( low ), Target( .), USL( up )) ),
... and again, we get:
Spec Limits( :Flight << {LSL( low ), Target( .), USL( up )} )wow! ... and arg!
So, let's use Plan B: which always works: use Eval(Substitute())
The original idea: in combination with Name Expr(As column(column_name))as the replacement expression
... but almost surprisingly, it even works with the bare string (!):
capability_chart = function({variable, low, up},
Eval(Substitute(Expr(Process Capability(
Process Variables( _var_ ), // select column for data
Spec Limits( _var_(LSL( low ), /*Target( 30 ),*/ USL( up )) ),
Individual Detail Reports( 1 ),
Capability Box Plots( 0 ),
Goal Plot( 0 ),
Capability Index Plot( 0 ),
Process Performance Plot( 0 ) // hide unnecessary info
)),Expr(_var_), variable
)));
capability_chart("Flight", 0, 10)