cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
  • Learn how to build custom Python data connectors and further customize JMP’s Data Connector Framework with the Python Data Connector Demo, available now in the JMP Marketplace!
  • See how to create experiments to support product design and ID useful product features. Register for June 12 webinar, 2pm US Eastern Time.

Discussions

Solve problems, and share tips and tricks with other JMP users.
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 XIII

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 XIII

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

Recommended Articles