cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
lemonses
Level I

JMP doesn't recognize my spec limits when column name is a variable in my user-defined function (JMP 17)

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.

1 ACCEPTED SOLUTION

Accepted Solutions
hogi
Level XII

Re: JMP doesn't recognize my spec limits when column name is a variable in my user-defined function (JMP 17)

Here is a list of tricks to make a JSL expression work:
Expression Handling in JMP: Tipps and Trapdoors 

 

Hints:

  1. 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.

  2. -> 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)

 

View solution in original post

2 REPLIES 2
hogi
Level XII

Re: JMP doesn't recognize my spec limits when column name is a variable in my user-defined function (JMP 17)

Here is a list of tricks to make a JSL expression work:
Expression Handling in JMP: Tipps and Trapdoors 

 

Hints:

  1. 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.

  2. -> 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)

 

jthi
Super User

Re: JMP doesn't recognize my spec limits when column name is a variable in my user-defined function (JMP 17)

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)

jthi_0-1717177178809.png

 

-Jarmo