Choose Language Hide Translation Bar
Highlighted
TheRealYeti
Level II

Is there a way to call a user function with different row filters

Sorry. I do not know how to best describe it in the title but I will try to elaborate what I currently have and what I wanted to achieve:

What I have:

So I have this function that computes for Col Min, Max and Mean

col_stats = Function( { COL_NAME }, {},
     curr_dt   = Cuurent Data Table();
     min_val   = Col Min   ( curr_dt:Eval(COL_NAME));
     max_val   = Col Max   ( curr_dt:Eval(COL_NAME));
     mean_val  = Col Mean  ( curr_dt:Eval(COL_NAME));
     Eval List({min_val, max_val, mean_val});
);

What I want to achieve:

I want to be able to call the col_stat function, filtering the data using the combination of a certain list or lists.

The number of lists can change based on user, for the example below the user select temp and vcc (user can add frequency etc)

temperature = {-40, 0, 25, 100};
vcc = {1.2, 1.26, 1.32};

I want to be able to get the Min Max Mean using the col_stat function for

-40 and 1.20V

-40 and 1.26V

and so on.

 

If the number of list are known, I know I can do a double for loop to iterate thru the combination of two lists but I want to expand it in such a way that the user can add more list

 

Hope I explained it well.

 

4 REPLIES 4
Highlighted
txnelson
Super User

Re: Is there a way to call a user function with different row filters

My thinking on this, is that you need to make a pretty simple change to your function to make it work only on rows that are selected in your data table.  The Show() with the call to your function is assuming that data table Big Class is open.

col_stats = Function( {dt, COL_NAME},
	{defaultlocal},
	min_val = Col Min( If( Selected( Row State( Row() ) ), column(dt, COL_NAME ), . ) );
	max_val = Col Max( If( Selected( Row State( Row() ) ), column(dt, COL_NAME ), . ) );
	mean_val = Col Mean( If( Selected( Row State( Row() ) ), column(dt, COL_NAME ), . ) );
	Return( Eval List( {min_val, max_val, mean_val} ) );
);


show(col_stats(dt,"height"));

By doing your calculations only on the selected rows, you can use the functionality of 

     dt << Select Where()

to define whatever combinations of items you want, and then to call the function and get the results.

And, you don't have to force everything into a single Select Where.  If you look at the definition of the Select Where, you will see that you can dynamically build your final overall selection passing several Select Where() clauses, and specifying whether to expand of contract from the current selection.(i.e. If all of the rows with -40 are currently selected, you can tell JMP to add the further qualification of "only the vcc of 1.20)

Jim
Highlighted

Re: Is there a way to call a user function with different row filters

Use a nested loop for the: { { temperatures}, { vccs } }?

Learn it once, use it forever!
Highlighted
TheRealYeti
Level II

Re: Is there a way to call a user function with different row filters

Doing a nested for loop would require hard coding two for-loops for the two lists, right?
I'd like to avoid that, because if the user add more list of filter like freq = {10, 20, 30} then that would not work , right ?
Id like it to work much like the "By" in Distribution if I add temp,wafer,vcc in the "By" list it would generate the distribution of all the combinations of temp,wafer & vcc. But I like it to work with my own function.
Highlighted

Re: Is there a way to call a user function with different row filters

 

If you're using a Where clause, you may find it a little faster to just get the values for the rows of interest and use the matrix methods:

 

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

col_stats = Function( {dt, rows, COL_NAME},
   {defaultlocal},
   vals = column(dt, COL_NAME )[rows];
   min_val = Min( vals );
   max_val = Max( vals );
   mean_val = Mean( vals );
   Return( Eval List( {min_val, max_val, mean_val} ) );
);

show(col_stats(dt, dt<<Get Rows Where(:age==13), "height"));
show(col_stats(dt, dt<<Get Rows Where(:age==14), "height"));

This does trade off a little memory for speed - You have two extra vectors, but it doesn't require any looping or conditionals in the JSL evaluation.

 

Article Labels