cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
J-Leonard
Level I

How to make script run for each sample in a list if there are multiple entries per sample in data table.

I have a data table where the same samples were measured multiple times (see example below). The samples are separated by their identifier.  

Capture.PNG

 

I want my script to be able to perform the same set of calculations on each sample so I can determine control limits and make a control chart for  A, B, C, etc. I do not know the identifier of each sample. I already have a script that can do my calculations and make the charts for me, it just cannot do separate calculations for each identifier. 

 

My initial through was to use some kind of loop to do this. I have a script that returns each unique identifier in a list and gives me the number of unique identifiers as a set up for the loop. 

Identifiers = Column( "Identifier") << GetAsMatrix();
Identifiers set = Associative Array( Identifiers);
Unique Identifiers = Identifiers set << Get Keys;

nUnique Identifiers = N Items (Unique Identifiers);

I just can't seem to get a loop to work though. Is there a better way to do this? Or could someone show me how to do the loop?

 

I am using JMP 10.

 

Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions
ih
Super User (Alumni) ih
Super User (Alumni)

Re: How to make script run for each sample in a list if there are multiple entries per sample in data table.

If you do not want to modify your script you could run it against a subset of each level of the identifier, like this:

 

Names default to here(1);

//Open some sample data
dt = Open( "$Sample_data/big class.jmp" );

//Your code
Identifiers = Column( "age") << GetAsMatrix();
Identifiers set = Associative Array( Identifiers);
Unique Identifiers = Identifiers set << Get Keys;

nUnique Identifiers = N Items (Unique Identifiers);

//A window to hold a bunch of graphs
win = New Window("Graphs", graphbox = v list box());

//Run an analysis on a subset of the data table for each level of a variable
for( i=1, i<=nUnique Identifiers, i++,
	//Make a subset of the table with only values for this level
	dt << Select Where( :age == UniqueIdentifiers[i]);
	dtSub = dt << Subset("Selected Rows");
	
	//run your existing script on the subset
	//For demonstration, taking a picture of the graph builder platform
	// and getting the R2 value from a linear model and adding those to a window
	pic = (gb = dtSub << Graph Builder(
			Size( 534, 456 ),
			Show Control Panel( 0 ),
			Variables( X( :height ), Y( :weight ) ),
			Elements( Points( X, Y, Legend( 2 ) ) ),
			Local Data Filter(
				Close Outline( 1 ),
				Add Filter(
					columns( :age ),
					Where( :age == Unique Identifiers[i] ),
					Display( :age, N Items( 6 ) )
				)
			)
		)) << Get Picture;
	graphbox << Append( pic );
	gb << Close Window;
	
	fm = dtSub << Fit Model(
		Y( :height ),
		Effects( :weight ),
		Personality( "Standard Least Squares" ),
		Emphasis( "Effect Leverage" ),
		Run(
			:height << {Summary of Fit( 1 ), Analysis of Variance( 1 ),
			Parameter Estimates( 1 ), Scaled Estimates( 0 ),
			Plot Actual by Predicted( 1 ), Plot Residual by Predicted( 1 ),
			Plot Studentized Residuals( 0 ), Plot Effect Leverage( 1 ),
			Plot Residual by Normal Quantiles( 0 ), Box Cox Y Transformation( 0 )}
		)
	);
	Wait( 0 );
	dtSum = Report( fm )[Outline Box( "Response height" )][Outline Box( "Whole Model" )][
		Outline Box( "Summary of Fit" )][Table Box( 1 )] << Make Into Data Table;
	Report( fm ) << Close Window;
	Rsq = dtSum:Column 2[1];
	
	graphbox << Append( Text Box( "RSquared was " || char(Rsq) ) );
	
	dtSum << Close Window;
	
	//close the subset
	dtSub << Close Window;
	
);

View solution in original post

5 REPLIES 5
ih
Super User (Alumni) ih
Super User (Alumni)

Re: How to make script run for each sample in a list if there are multiple entries per sample in data table.

There are lots of ways to do this, but one is to just add a local data filter to your existing platforms.  Here is an example using graph builder:

 

Names default to here(1);

//Open some sample data
dt = Open( "$Sample_data/big class.jmp" );

//Your code
Identifiers = Column( "age") << GetAsMatrix();
Identifiers set = Associative Array( Identifiers);
Unique Identifiers = Identifiers set << Get Keys;

nUnique Identifiers = N Items (Unique Identifiers);

//A window to hold a bunch of graphs
win = New Window("Graphs", graphbox = v list box());

//Open a graph that is filtered to only show each unique identifier
//to keep things organized add it to a single window.
for( i=1, i<=nUnique Identifiers, i++,
	win << Append(
//To get this script I opened graph builder and added a local data filter for one age
//and then copied/pasted it here and replaced the age with 4Unique Identifiers[i] Graph Builder( Size( 534, 456 ), Show Control Panel( 0 ), Variables( X( :height ), Y( :weight ) ), Elements( Points( X, Y, Legend( 2 ) ) ), Local Data Filter( Close Outline( 1 ), Add Filter( columns( :age ), Where( :age == Unique Identifiers[i] ), Display( :age, N Items( 6 ) ) ) ) ) ) );
J-Leonard
Level I

Re: How to make script run for each sample in a list if there are multiple entries per sample in data table.

How would I be able to do additional calculations filtered by the identifier? I want to do some data manipulation and then calculate my own limits based on the data per identifier which would then be added to each of the charts, so I think any kind of filter would need to come before the final chart script. I have a script that can do that and I can post it if needed, but it is pretty long. I am really just looking for a way to make the script I already have run for each identifier rather than all of the rows in the data table 

ih
Super User (Alumni) ih
Super User (Alumni)

Re: How to make script run for each sample in a list if there are multiple entries per sample in data table.

If you do not want to modify your script you could run it against a subset of each level of the identifier, like this:

 

Names default to here(1);

//Open some sample data
dt = Open( "$Sample_data/big class.jmp" );

//Your code
Identifiers = Column( "age") << GetAsMatrix();
Identifiers set = Associative Array( Identifiers);
Unique Identifiers = Identifiers set << Get Keys;

nUnique Identifiers = N Items (Unique Identifiers);

//A window to hold a bunch of graphs
win = New Window("Graphs", graphbox = v list box());

//Run an analysis on a subset of the data table for each level of a variable
for( i=1, i<=nUnique Identifiers, i++,
	//Make a subset of the table with only values for this level
	dt << Select Where( :age == UniqueIdentifiers[i]);
	dtSub = dt << Subset("Selected Rows");
	
	//run your existing script on the subset
	//For demonstration, taking a picture of the graph builder platform
	// and getting the R2 value from a linear model and adding those to a window
	pic = (gb = dtSub << Graph Builder(
			Size( 534, 456 ),
			Show Control Panel( 0 ),
			Variables( X( :height ), Y( :weight ) ),
			Elements( Points( X, Y, Legend( 2 ) ) ),
			Local Data Filter(
				Close Outline( 1 ),
				Add Filter(
					columns( :age ),
					Where( :age == Unique Identifiers[i] ),
					Display( :age, N Items( 6 ) )
				)
			)
		)) << Get Picture;
	graphbox << Append( pic );
	gb << Close Window;
	
	fm = dtSub << Fit Model(
		Y( :height ),
		Effects( :weight ),
		Personality( "Standard Least Squares" ),
		Emphasis( "Effect Leverage" ),
		Run(
			:height << {Summary of Fit( 1 ), Analysis of Variance( 1 ),
			Parameter Estimates( 1 ), Scaled Estimates( 0 ),
			Plot Actual by Predicted( 1 ), Plot Residual by Predicted( 1 ),
			Plot Studentized Residuals( 0 ), Plot Effect Leverage( 1 ),
			Plot Residual by Normal Quantiles( 0 ), Box Cox Y Transformation( 0 )}
		)
	);
	Wait( 0 );
	dtSum = Report( fm )[Outline Box( "Response height" )][Outline Box( "Whole Model" )][
		Outline Box( "Summary of Fit" )][Table Box( 1 )] << Make Into Data Table;
	Report( fm ) << Close Window;
	Rsq = dtSum:Column 2[1];
	
	graphbox << Append( Text Box( "RSquared was " || char(Rsq) ) );
	
	dtSum << Close Window;
	
	//close the subset
	dtSub << Close Window;
	
);
J-Leonard
Level I

Re: How to make script run for each sample in a list if there are multiple entries per sample in data table.

Works like a charm, thank you!

Re: How to make script run for each sample in a list if there are multiple entries per sample in data table.

I wonder if using the built-in control chart platforms to calculate limits and plot measures would work, especially if you assign Identifier to the By analysis role.

 

Just don't want you to spend a lot of time scripting if it duplicates what functionality is already available.