cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Have your say in shaping JMP's future by participating in the new JMP Wish List Prioritization Survey
Choose Language Hide Translation Bar
LaserGuy
Level II

Function to Count Rows Within Spec

I want to create a function that reads in a column, checks the number in each row on whether it is within spec, and output the passing count/total count/percentages.

 

This is what I have:

count_in_spec = Function( { col, lsl, usl },
	a=0; //pass count
	b=0; //all count
	for( i = 1, i <= N Rows(col), i++,
		if( col[i] >= lsl & col[i] <= usl, a++ );
		if( not(ismissing(col[i])), b++ );
	);
	pctpass = 100*a/b;
	pctfail = 100 - pctpass;
	
	evallist({a, b, pctpass, pctfail});
);


dt0 = current data table();
colp = dt0:name("param") << get as matrix;

results = count_in_spec(colp, 0.15, 0.30 );
	countpass = results[1];
	countall = results[2];
	pctpass = results[3];
	pctfail = results[4];

While this works, I don't like the fact that I need to use "get as matrix". It's a bit clunky.

 

I would like a function that works simply by writing:

results = count_in_spec( "param name", lsl, usl);

 

How would I modify my function so it can work this way?

3 ACCEPTED SOLUTIONS

Accepted Solutions

Re: Function to Count Rows Within Spec

EDIT: I can no longer recommend this solution--use MS's: it shows a way to do this using a column formula; not only should it run faster, but column formulas also have the benefit of supporting grouping variables.

-Brady

 

Hi,

 

You can use the built-in matrix functions for this. I use <<get as matrix within the function, but I'm not sure how you'd avoid that without making the script more cumbersome.

 

Cheers,

Brady

 

Names Default To Here(1);

dt = astable(J(1000, 1, randomnormal(0,3)), <<column names ({x}));
	
count_in_spec = function({col, lsl, usl},
	{default local},
	vals = column(dt, col) << get as matrix;
	vals = vals[loc(!is missing (vals))];		//remove missing rows
	nr = nrow(vals);							//get number of rows
	nPass = sum(lsl <= vals <= usl);			
	evallist({nPass, nr, 100*nPass/nr, 100*(nr-nPass)/nr})  //be sure to EVAL the list!
);

//test it out...
{countpass, countall, pctpass, pctfail} = count_in_spec("x", -3, 4);

 

View solution in original post

txnelson
Super User

Re: Function to Count Rows Within Spec

Using the Get Rows Where() function should get you want you want

sr1.PNG

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/semiconductor capability.jmp" );

count_in_spec = Function( {col, lsl, usl},
	result = N Rows( dt << get rows where( lsl <= As Column( dt, col ) <= usl ) )
);

colNames = dt << get column names(string, continuous);

resultColList = {};
resultCountList = {};

For(i=1,i<= 10 /*Nitems(colNames)*/,i++,
	specs = column(dt,colNames[i]) << get property("spec limits");
	If(isMissing(try(specs["LSL"],.))==0 & isMissing(try(specs["USL"],.))==0,
		result = count_in_spec(colNames[i],specs["LSL"],specs["USL"]);
		insert into(resultColList,colNames[i]);
		insert into(resultCountList,result)
	)
);

new window("Results",
	outline box("In Spec Report",
		Table Box(
			string col box("Column", resultColList),
			number col box("Count", resultCountList)
		)
	)
);
Jim

View solution in original post

ms
Super User (Alumni) ms
Super User (Alumni)

Re: Function to Count Rows Within Spec

The Col Stat() functions are often efficient for directly summarizing table data, also with conditionals involved. Here's an example without the need for a matrix step.

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

count_in_spec = Function( {col, lsl, usl},
	{default local},
	a = Col Sum( lsl < As Column( col ) < usl );
	b = Col Number( col );
	pctpass = 100 * a / b;
	pctfail = 100 - pctpass;
	Eval List( {a, b, pctpass, pctfail} );
);

results = count_in_spec( Column( dt, "height" ), 55, 70 );
countpass = results[1];
countall = results[2];
pctpass = results[3];
pctfail = results[4];

 

View solution in original post

4 REPLIES 4

Re: Function to Count Rows Within Spec

EDIT: I can no longer recommend this solution--use MS's: it shows a way to do this using a column formula; not only should it run faster, but column formulas also have the benefit of supporting grouping variables.

-Brady

 

Hi,

 

You can use the built-in matrix functions for this. I use <<get as matrix within the function, but I'm not sure how you'd avoid that without making the script more cumbersome.

 

Cheers,

Brady

 

Names Default To Here(1);

dt = astable(J(1000, 1, randomnormal(0,3)), <<column names ({x}));
	
count_in_spec = function({col, lsl, usl},
	{default local},
	vals = column(dt, col) << get as matrix;
	vals = vals[loc(!is missing (vals))];		//remove missing rows
	nr = nrow(vals);							//get number of rows
	nPass = sum(lsl <= vals <= usl);			
	evallist({nPass, nr, 100*nPass/nr, 100*(nr-nPass)/nr})  //be sure to EVAL the list!
);

//test it out...
{countpass, countall, pctpass, pctfail} = count_in_spec("x", -3, 4);

 

txnelson
Super User

Re: Function to Count Rows Within Spec

Using the Get Rows Where() function should get you want you want

sr1.PNG

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/semiconductor capability.jmp" );

count_in_spec = Function( {col, lsl, usl},
	result = N Rows( dt << get rows where( lsl <= As Column( dt, col ) <= usl ) )
);

colNames = dt << get column names(string, continuous);

resultColList = {};
resultCountList = {};

For(i=1,i<= 10 /*Nitems(colNames)*/,i++,
	specs = column(dt,colNames[i]) << get property("spec limits");
	If(isMissing(try(specs["LSL"],.))==0 & isMissing(try(specs["USL"],.))==0,
		result = count_in_spec(colNames[i],specs["LSL"],specs["USL"]);
		insert into(resultColList,colNames[i]);
		insert into(resultCountList,result)
	)
);

new window("Results",
	outline box("In Spec Report",
		Table Box(
			string col box("Column", resultColList),
			number col box("Count", resultCountList)
		)
	)
);
Jim
ms
Super User (Alumni) ms
Super User (Alumni)

Re: Function to Count Rows Within Spec

The Col Stat() functions are often efficient for directly summarizing table data, also with conditionals involved. Here's an example without the need for a matrix step.

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

count_in_spec = Function( {col, lsl, usl},
	{default local},
	a = Col Sum( lsl < As Column( col ) < usl );
	b = Col Number( col );
	pctpass = 100 * a / b;
	pctfail = 100 - pctpass;
	Eval List( {a, b, pctpass, pctfail} );
);

results = count_in_spec( Column( dt, "height" ), 55, 70 );
countpass = results[1];
countall = results[2];
pctpass = results[3];
pctfail = results[4];

 

LaserGuy
Level II

Re: Function to Count Rows Within Spec

Thank you everyone. I have explored all three categories of methods. I then realized I could have made things a bit easier for myself by using something like this:

 

dt0 = current data table();
	dt0 << clear row states;

count_in_spec = Function( { col, lsl, usl },
	a=0; //pass count
	b=0; //all count
	
	cola = dt0:col << get as matrix;
	for( i = 1, i <= N Rows( cola ), i++,
			if( cola[i] >= lsl & cola[i] <= usl, a++ );
			if( not(ismissing( cola[i] )), b++ );
	);

	pctpass = 100*a/b;
	pctfail = 100 - pctpass;
	
	evallist({a, b, pctpass, pctfail});
);



colp = "param1";

results = count_in_spec(colp, 0.15, 0.30 );
	countpass = results[1];
	countall = results[2];
	pctpass = results[3];
	pctfail = results[4];

show(countpass);
show(countall);
show(pctpass);
show(pctfail);


colp = "param2";

results = count_in_spec(colp, 0.15, 0.30);
	countpass = results[1];
	countall = results[2];
	pctpass = results[3];
	pctfail = results[4];

show(countpass);
show(countall);
show(pctpass);
show(pctfail);

The syntax for extracting LSL and USL properties from a column will be useful.