BookmarkSubscribeSubscribe to RSS Feed
Highlighted
JohnTM

Occasional Contributor

Joined:

May 17, 2018

Extract data from a oneway analysis

I am trying to create a script to take the p-value from the oneway analysis and drop that into a new column in the table used for the analysis. 

 

I looked over the JMP 13 scripting guide and on page 690, there is "Extract Values from an Analysis into a Report" which seems to be what I want. However following that as a guide, it does not appear to work with oneway and anovas...

 

Here is the listed script I modified to work with the bigclass sample dataset while I was trying to troubleshoot the code:

 

Deletesymbols();

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

//creates a oneway analysis of big class similar how my data will be interpreted 
anova=Oneway(
		Y(:height),
		X(:age), 
		With Control(1, {12}),
		Means(1), Mean Diamonds(1), Comparison Circles(1),
		By(:sex)  
		);
		
anova<<show tree structure;
/*
Female LDS threshold results are in OultineBox(9), Levels (age) is StringColBox(5), pValues are NumberColBox(15)
Male LDS threshold results are in OultineBox(18), Levels (age) is StringColBox(10), pValues are NumberColBox(30)
*/

// Should create a report that I can use to extract data from the anova analysis based off the original script
report(anova) [Outline Box(9)] &lt;&lt; Close( 0 ); <br>report(anova) [Outline Box(18)] &lt;&lt; Close( 0 );
reportanova = anova &lt;&lt; Report; 

// Should extract the level (age) and pvalues for females
agef = reportanova[Outline Box(9)][String Col Box(5)] &lt;&lt; Getaslist;
pvalsf = reportanova[Outline Box(9)][NumberColBox(15)] &lt;&lt; Getaslist;

// Should extract the level (age) pvalues for males
agem = reportanova[Outline Box(18)][String Col Box(10)] &lt;&lt; Getaslist;
pvalsm = reportanova[Outline Box(18)][NumberColBox(30)] &lt;&lt; Getaslist;

//column creation to recieve extracted data
dt&lt;&lt;new column("p-value",Numeric, "Continuous");

//should add the collected p-value to the data table in the new column, matched to the correct row based on sex and age <font color="#FF0000">(untested)</font>.

For Each Row( p-value =
		match(sex,
			"f",match(age,
				show(agef[1]),show(pvalsf[1]),		
				show(agef[2]),show(pvalsf[2]),	
				show(agef[3]),show(pvalsf[3]),	
				show(agef[4]),show(pvalsf[4]),	
				show(agef[5]),show(pvalsf[5]),	
				show(agef[6]),show(pvalsf[6]),	
				
			),
	 
			"m",match(age,
				show(agem[1]),show(pvalsm[1]),		
				show(agem[2]),show(pvalsm[2]),	
				show(agem[3]),show(pvalsm[3]),	
				show(agem[4]),show(pvalsm[4]),	
				show(agem[5]),show(pvalsm[5]),	
				show(agem[6]),show(pvalsm[6]),	
		),
	
);*/

But the embedded log has an error when putting the anova into a report:

 

 

Send Expects Scriptable Object in access or evaluation of 'Send' , Report( anova )[Outline Box( 9 )] << /*###*/Close( 0 ) /*###*/

 

The debugger fails at the same place and gives these as the variables:

Variable          Value

anova             {Oneway[],Oneway[]}

dt                    Data Table("big Class")

reportanova    {DisplayBox[OutlineBox], DisplayBox[OutlineBox]}

 

So I can only guess that what works with Bivariate does not extend to Oneway.  I even changed the variables, shortening anova to anov in case it was a variable/command/something mismatch, but it continues to fail.  There was a previous post from 2011 with a sample code, but it was garbled with font info that wouldn't clear up in word, a jmp script window, or saving as a html file so I could actually read it...

 

This I have to solve before I can see if my code to add the p-value to the correct row works...

 

Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
markbailey

Staff

Joined:

Jun 23, 2011

Solution

Re: Extract data from a oneway analysis

There are general rules and syntax that apply to all JMP platforms (reports) but the composition (i.e., specific nested display boxes) varies, of course. Try this approach:

Names Default To Here( 1 );

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

//creates a oneway analysis of big class similar how my data will be interpreted 
anova = dt << Oneway(
	Y( :height ),
	X( :age ),
	With Control( 1, {12} ),
	Means( 1 ),
	Mean Diamonds( 1 ),
	Comparison Circles( 1 ),
	By( :sex )
);

anova rpt = anova << Report;

f ages = anova rpt[1]["LSD Threshold Matrix"][StringColBox(1)] << Get;
f pVal = anova rpt[1]["LSD Threshold Matrix"][NumberColBox(2)] << Get;

m ages = anova rpt[2]["LSD Threshold Matrix"][StringColBox(1)] << Get;
m pVal = anova rpt[2]["LSD Threshold Matrix"][NumberColBox(2)] << Get;
Learn it once, use it forever!
5 REPLIES
markbailey

Staff

Joined:

Jun 23, 2011

Solution

Re: Extract data from a oneway analysis

There are general rules and syntax that apply to all JMP platforms (reports) but the composition (i.e., specific nested display boxes) varies, of course. Try this approach:

Names Default To Here( 1 );

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

//creates a oneway analysis of big class similar how my data will be interpreted 
anova = dt << Oneway(
	Y( :height ),
	X( :age ),
	With Control( 1, {12} ),
	Means( 1 ),
	Mean Diamonds( 1 ),
	Comparison Circles( 1 ),
	By( :sex )
);

anova rpt = anova << Report;

f ages = anova rpt[1]["LSD Threshold Matrix"][StringColBox(1)] << Get;
f pVal = anova rpt[1]["LSD Threshold Matrix"][NumberColBox(2)] << Get;

m ages = anova rpt[2]["LSD Threshold Matrix"][StringColBox(1)] << Get;
m pVal = anova rpt[2]["LSD Threshold Matrix"][NumberColBox(2)] << Get;
Learn it once, use it forever!
JohnTM

Occasional Contributor

Joined:

May 17, 2018

Re: Extract data from a oneway analysis

That works, Thanks!

 

So for anyone else looking here... and to make sure I am understanding and not just copying and pasting code, in :

 

f ages = anova rpt[1]["LSD Threshold Matrix"][StringColBox(1)] << Get;

The 'By()' option in the oneway creates two separate instances within the report, I am guessing this is why '<<show tree structure' pops up two different windows, so 'anova rpt[#]' is needed to specify which section we want to extract the data from, in this example:

anova rpt[1]

 is pointing to the first group created from 'By(:sex)' when creating the oneway, which is 'F', and 'anova rpt[2]' refers to group 2 'M'.  The original script from the scripting guide didn't need it as there was only one section in the report to deal with when it was a simple bivariate?  

 

Then the segment :

["LSD Threshold Matrix"][StringColBox(1)]

lets jmp skip straight to the "LSD Threshold Matrix" section of the report and resets the numbering scheme which is why the string column is now refrenced by ...Box(1), but for the entire tree structure, it is ...Box(5).  With all three of these being equivalent ways of getting the refrenced female ages list from the tree structure:

f ages = anova rpt[1]["LSD Threshold Matrix"][StringColBox(1)] << Get;
f ages = anova rpt[1][Outline Box(9)][StringColBox(1)] << Get;
f ages = anova rpt[1][StringColBox(5)] << Get;

Then if the By (:sex) is commented out from the one way, the tree structure is simplified and:

ages = anova rpt[1][StringColBox(5)] << Get;
ages = anova rpt[StringColBox(5)] << Get;

both work now because the [1] is understood, and does not need to be specified as [2] is no longer even an option.

markbailey

Staff

Joined:

Jun 23, 2011

Re: Extract data from a oneway analysis

One strong recommendation for something that we teach as a 'best practice:' don't use the absolute indexes that are shown in the display tree diagram. You can write correct subscripts this way, so why not? Because this way is difficult to compose, read, and, therefore, maintain, and it is brittle. Use the relative indexing as illustrated in my solution. It is easier to write, read (self-documenting?), and maintain. It is also a lot less brittle. Be selfish and think only of yourself!

Remember that JMP changes, too: versions introduce new sections in reports or move sections, you change your platform preferences, someone else uses your script with different preferences, and so on. Defensive scripting anticipates such variation. Relative indexes are robust against it.

Some people think that this choice is just a matter of style. I hope that they never suffer from change.

(And don't get me started on using the Send To Report interpreter directive...)

Learn it once, use it forever!
JohnTM

Occasional Contributor

Joined:

May 17, 2018

Re: Extract data from a oneway analysis

Should anyone also want to see how I got the adding the value back to the table matched to sex and age working:

 

//creates a new column
dt<<new column("pvalue", Character, "Ordinal");

//age needs to be changed to character (or you could probably change the list to numbers)
Column("age") << Data Type( Character ); 

//Adds the p-value to the row correctly matched by sex and age
For Each Row(:pvalue=
		if(:sex=="F" & :age == agef[1],pvalsf[1],
			:sex=="F" & :age == agef[2],pvalsf[2],	
			:sex=="F" & :age == agef[3],pvalsf[3],	
			:sex=="F" & :age == agef[4],pvalsf[4],	
			:sex=="F" & :age == agef[5],pvalsf[5],	
			:sex=="F" & :age == agef[6],pvalsf[6],
			:sex=="M" & :age == agem[1],pvalsm[1],
			:sex=="M" & :age == agem[2],pvalsm[2],
			:sex=="M" & :age == agem[3],pvalsm[3],
			:sex=="M" & :age == agem[4],pvalsm[4],	
			:sex=="M" & :age == agem[5],pvalsm[5],
			:sex=="M" & :age == agem[6],pvalsm[6],
			"match error"
));

There may be an easier or neater way to do this, but it works. Nested if statements and for loops worked too as soon as I realized the mismatch of the Data type of the original age as 'number', and the list from "LSD Threshold Matrix" was 'character'.

John_Powell_JMP

Joined:

May 30, 2014

Re: Extract data from a oneway analysis

For what it's worth, I cleaned up the garbled post from 2011.