<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: [JSL] Script for Two-One Side T-Test on a large number of metrics in Discussions</title>
    <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/785584#M96899</link>
    <description>&lt;P&gt;Is there a reason you cannot use the &lt;A href="https://www.jmp.com/support/help/en/18.0/#page/jmp/the-oneway-platform-options.shtml#" target="_self"&gt;built-in equivalence test&lt;/A&gt; in the Oneway platform?&lt;/P&gt;</description>
    <pubDate>Tue, 27 Aug 2024 12:18:31 GMT</pubDate>
    <dc:creator>Mark_Bailey</dc:creator>
    <dc:date>2024-08-27T12:18:31Z</dc:date>
    <item>
      <title>[JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/784629#M96881</link>
      <description>&lt;P&gt;Hello All,&lt;/P&gt;&lt;P&gt;I would like to write a JSL script to automate a TOST (Two-One Side T-Test) on a large number of metrics (500+).&lt;/P&gt;&lt;P&gt;The TOST works by pair of “levels”, so working with 2x levels is easy, because it requires only 1x row per “pair”.&lt;/P&gt;&lt;P&gt;I already wrote a script that works well for 2x levels by generating a “Combined data table” and adding more columns with formula to it, which end up with the results: “Equivalent” or “Not Equivalent”.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The problem thickens when I want to work with more than 2x Levels, it would require to find all possible unique pairs of “Levels” and then run the TOST math for every combination of Metric + pairs of Levels.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I found a way (on this forum) to find all possible unique pairs from a list and put them in a table or in a nested list (NchooseKmatrix()).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;But I am stuck there. What I need is:&lt;/P&gt;&lt;P&gt;1-&lt;SPAN class=""&gt;&amp;nbsp; &lt;/SPAN&gt;to populate a new table with all possible combinations of Metrics (Column1) and all pairs of possible levels (Column2 and Column3).&lt;/P&gt;&lt;P&gt;2- Then add the stats for each pair of level on each row&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;From this point I will be able to figure out the math to finalize the TOST.&lt;/P&gt;&lt;P&gt;I have attached a script that generates a dummy table, then a combined data table from the Oneway analysis, then my unsuccessful attempt of creating a third table with all combinations of Metrics + Unique pairs of level&lt;/P&gt;&lt;P&gt;Thanks in advance for your help&lt;SPAN class=""&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here( 1 );
clear symbols();
Deletesymbols();

//Create table with random distribution (table 1)
dt = New Table( "tabletest",
	Add Rows( 500 ),
	New Column( "Product", Character, "Nominal", formula("Product " ||char( Random Integer( 1, 4 )))),
	New Column( "Metric1", Numeric, "Continuous", formula( Random Normal( 10, 1 ) ) ),
	New Column( "Metric2", Numeric, "Continuous", formula( Random Gamma( 10, 1 ) ) ),
	New Column( "Metric3", Numeric, "Continuous", formula( Random Gamma( 10, 2 ) ) )

	
);
Column( dt, "Metric1" ) &amp;lt;&amp;lt; set property( "spec limits", {LSL( 5 ), USL( 25 ), Show Limits( 0 )} );
Column( dt, "Metric2" ) &amp;lt;&amp;lt; set property( "spec limits", {LSL( 0 ), USL( 40 ), Show Limits( 0 )} );
Column( dt, "Metric3" ) &amp;lt;&amp;lt; set property( "spec limits", {LSL( 5 ), USL( 40 ), Show Limits( 0 )} );

dt &amp;lt;&amp;lt; save( "$Desktop\tabletest.jmp" );

//Get a list from all unique Product

SplitBy = "Product";
summarize(ColumnSplitBy=by(Column (SplitBy)));
show(ColumnSplitBy);
For( i = N Items( ColumnSplitBy ), i &amp;gt; 0, i--,
  If( ColumnSplitBy[i] == "",
  Remove From( ColumnSplitBy, i, 1 );
  )
);

//Get Column name
MetricCols = dt &amp;lt;&amp;lt; Get Column Names( numeric, continuous, "string" );

//Get all unique combo of 2 Products
ColumnSplitByCombo = aslist( nchoosekMatrix(nitems(ColumnSplitBy), 2));
show (ColumnSplitByCombo);


//Create a combinaed datatable with stats (Table 2)
ow = dt &amp;lt;&amp;lt; Oneway(
	Y(Eval(MetricCols)),
	X(Eval(SplitBy)),
	Means and Std Dev(1),
	SendToReport(
		Dispatch(
			{"Means and Std Deviations"},
			"Std Dev Lower 95%",
			NumberColBox,
			{Visibility("Visible")}
		),
		Dispatch(
			{"Means and Std Deviations"},
			"Std Dev Upper 95%",
			NumberColBox,
			{Visibility("Visible")}
		)
	),
	Invisible
);

tb = Report(ow[1])[Outline Box("Means and Std Deviations"), Table Box(1)];
dt2 = tb &amp;lt;&amp;lt; Make Combined Data Table;
tb &amp;lt;&amp;lt; close window;

//Create new table for the result, each row has a unique pair of Levels  
dt3 = astable( nchoosekMatrix(nitems(ColumnSplitBy), 2), &amp;lt;&amp;lt; column names({"x", "y"}) );
dt3 &amp;lt;&amp;lt; new column ("first", character, &amp;lt;&amp;lt; set values ( ColumnSplitBy[dt3:x &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; new column ("second", character, &amp;lt;&amp;lt; set values ( ColumnSplitBy[dt3:y &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; delete columns (1::2);

//Create a nested list with each pair of levels
Listdt3 = aslist( nchoosekMatrix(nitems(ColumnSplitBy), 2));
show (Listdt3);

// I tried to use associate array() to match the level and name but couldn't make it work&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;-Voiz&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 03:03:39 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/784629#M96881</guid>
      <dc:creator>Voizingu</dc:creator>
      <dc:date>2024-08-27T03:03:39Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/784868#M96882</link>
      <description>&lt;P&gt;I attached a document "Untitled.png" with screenshots to (hopefully) better explain my request.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 05:53:43 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/784868#M96882</guid>
      <dc:creator>Voizingu</dc:creator>
      <dc:date>2024-08-27T05:53:43Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/784894#M96883</link>
      <description>&lt;P&gt;You could for example first stack your group column, update it with the results and split it again.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This example doesn't take into account that there can be multiple Metrics&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;// Loop over Metrics and perform these for each of them
// Concatenate results into single table
dt3 = As Table(NChooseK Matrix(N Items(ColumnSplitBy), 2), &amp;lt;&amp;lt;column names({"x", "y"}));
dt3 &amp;lt;&amp;lt; New Column("first", character, &amp;lt;&amp;lt;set values(ColumnSplitBy[dt3:x &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; New Column("second", character, &amp;lt;&amp;lt;set values(ColumnSplitBy[dt3:y &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; new column("R", Numeric, Ordinal, Formula(Row()));
dt4 = dt3 &amp;lt;&amp;lt; Stack(
	columns(:first, :second),
	Source Label Column("Label"),
	Stacked Data Column("Data"),
	"Non-stacked columns"n(Keep(:R)),
);
close(dt3, no save);&lt;BR /&gt;// Metrics should be taken into account here OR stacked table should contain them
dt4 &amp;lt;&amp;lt; Update(
	With(dt2),
	Match Columns(:Data = :Level)
);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;or doesn't have the final split which most likely looks something like this&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_0-1724738829675.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67563i6B83B09443EEF397/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_0-1724738829675.png" alt="jthi_0-1724738829675.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 06:10:35 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/784894#M96883</guid>
      <dc:creator>jthi</dc:creator>
      <dc:date>2024-08-27T06:10:35Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/785229#M96888</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.jmp.com/t5/user/viewprofilepage/user-id/54797"&gt;@Voizingu&lt;/a&gt;&amp;nbsp;: The TOST is just checking to see if the 100(1-2alpha)% confidence interval is contained entirely within some equivalence limits; so, perhaps an adequate workaround would be to use the Fit Y by X multiple comparisons procedure to do all the combinations for you?&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 08:27:36 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/785229#M96888</guid>
      <dc:creator>MRB3855</dc:creator>
      <dc:date>2024-08-27T08:27:36Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/785584#M96899</link>
      <description>&lt;P&gt;Is there a reason you cannot use the &lt;A href="https://www.jmp.com/support/help/en/18.0/#page/jmp/the-oneway-platform-options.shtml#" target="_self"&gt;built-in equivalence test&lt;/A&gt; in the Oneway platform?&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 12:18:31 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/785584#M96899</guid>
      <dc:creator>Mark_Bailey</dc:creator>
      <dc:date>2024-08-27T12:18:31Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/785983#M96907</link>
      <description>&lt;P&gt;Hello Jarmo,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Stack &amp;gt; Update &amp;gt; Split is a great idea!!!&lt;/P&gt;&lt;P&gt;I have been able to implement it successfully, but my code is a bit dirty (a lot of For() loops, intermediate steps,...).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Instead of:&lt;/P&gt;&lt;P&gt;- Concatenate the table multiple times&lt;/P&gt;&lt;P&gt;- Then populating a column from a list of repeated metrics&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I would like to become better in optimizing my code.&lt;/P&gt;&lt;P&gt;Is there a way to populate dt5 in a more cleaner/optimized way? (use native JMP commands maybe?)&lt;/P&gt;&lt;P&gt;I would love your suggestions on this&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;But anyway, thanks a lot for helping me on this :D&lt;/img&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;-Voiz&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here( 1 );
clear symbols();
Deletesymbols();

//Create table with random distribution (table 1)
dt = New Table( "tabletest",
	Add Rows( 5000 ),
	New Column( "Product", Character, "Nominal", formula("Product " ||char( Random Integer( 1, 4 )))),
	New Column( "Metric1", Numeric, "Continuous", formula( Random Normal( 10, 1 ) ) ),
	New Column( "Metric2", Numeric, "Continuous", formula( Random Gamma( 10, 1 ) ) ),
	New Column( "Metric3", Numeric, "Continuous", formula( Random Gamma( 10, 2 ) ) ),
	
);
Column( dt, "Metric1" ) &amp;lt;&amp;lt; set property( "spec limits", {LSL( 5 ), USL( 25 ), Show Limits( 0 )} );
Column( dt, "Metric2" ) &amp;lt;&amp;lt; set property( "spec limits", {LSL( 0 ), USL( 40 ), Show Limits( 0 )} );
Column( dt, "Metric3" ) &amp;lt;&amp;lt; set property( "spec limits", {LSL( 5 ), USL( 40 ), Show Limits( 0 )} );

dt &amp;lt;&amp;lt; save( "$Desktop\tabletest.jmp" );

//Get a list from all unique Product

SplitBy = "Product";
summarize(ColumnSplitBy=by(Column (SplitBy)));
show(ColumnSplitBy);
For( i = N Items( ColumnSplitBy ), i &amp;gt; 0, i--,
  If( ColumnSplitBy[i] == "",
  Remove From( ColumnSplitBy, i, 1 );
  )
);

//Get Column name
MetricCols = dt &amp;lt;&amp;lt; Get Column Names( numeric, continuous, "string" );
show(MetricCols);

//Get all unique combo of 2 Products
ColumnSplitByCombo = aslist( nchoosekMatrix(nitems(ColumnSplitBy), 2));
show (ColumnSplitByCombo);


//Create a combinaed datatable with stats (Table 2)
ow = dt &amp;lt;&amp;lt; Oneway(
	Y(Eval(MetricCols)),
	X(Eval(SplitBy)),
	Means and Std Dev(1),
	SendToReport(
		Dispatch(
			{"Means and Std Deviations"},
			"Std Dev Lower 95%",
			NumberColBox,
			{Visibility("Visible")}
		),
		Dispatch(
			{"Means and Std Deviations"},
			"Std Dev Upper 95%",
			NumberColBox,
			{Visibility("Visible")}
		)
	),
	Invisible
);

tb = Report(ow[1])[Outline Box("Means and Std Deviations"), Table Box(1)];
dt2 = tb &amp;lt;&amp;lt; Make Combined Data Table;
tb &amp;lt;&amp;lt; close window;


//Create new table for the result, each row has a unique pair of Levels  
dt3 = astable( nchoosekMatrix(nitems(ColumnSplitBy), 2), &amp;lt;&amp;lt; column names({"x", "y"}) );
dt3 &amp;lt;&amp;lt; new column ("first", character, &amp;lt;&amp;lt; set values ( ColumnSplitBy[dt3:x &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; new column ("second", character, &amp;lt;&amp;lt; set values ( ColumnSplitBy[dt3:y &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; delete columns (1::2);

//Create a nested list with each pair of levels
Listdt3 = aslist( nchoosekMatrix(nitems(ColumnSplitBy), 2));
show (Listdt3);

// I tried to use associate array() to match the level and name but couldn't make it work

// Loop over Metrics and perform these for each of them
// Concatenate results into single table
dt3 = As Table(NChooseK Matrix(N Items(ColumnSplitBy), 2), &amp;lt;&amp;lt;column names({"x", "y"}));
dt3 &amp;lt;&amp;lt; New Column("first", character, &amp;lt;&amp;lt;set values(ColumnSplitBy[dt3:x &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; New Column("second", character, &amp;lt;&amp;lt;set values(ColumnSplitBy[dt3:y &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; new column("R", Numeric, Ordinal, Formula(Row()));
dt4 = dt3 &amp;lt;&amp;lt; Stack(
	columns(:first, :second),
	Source Label Column("Label"),
	Stacked Data Column("Data"),
	"Non-stacked columns"n(Keep(:R)),
);
close(dt3, no save);

// create final table 
dt5 = New Table("final",
	New Column( "R", Character, "Nominal"),
	New Column( "Label", Character, "Nominal"),
	New Column( "Data", Character, "Nominal")
);

// create the Metric list to populate into dt5 metric column &amp;lt;-- not very clean
MetricListFinal = {};
For (k=1, k&amp;lt;=N items(MetricCols), k++,
	For(j=1, j&amp;lt;=N rows(dt4), j++,
		Insert into(MetricListFinal, MetricCols[k]);
));
show(MetricListFinal);

// concatenate the stacked list of unique pairs of level &amp;lt;-- not very clean
For(i=1, i&amp;lt;=N items(MetricCols), i++,
	dt5 &amp;lt;&amp;lt; concatenate(data table(dt4), append to first table(1));
);

// populate the column with the list of metrics &amp;lt;-- not very clean
dt5 &amp;lt;&amp;lt; New Column( "Metric", Character, "Nominal", values(MetricListFinal));

// update table from Combined stats table 
dt5 &amp;lt;&amp;lt; Update(
	With(dt2),
	Match Columns(:Data = :Level, :Metric = :Y )
);

// split table by level
dt5 &amp;lt;&amp;lt; Split(
	Split By( :Label ),
	Split(
		:Metric, :Data, :Number, :Mean, :Std Dev, :Std Err Mean, :Lower 95%,
		:Upper 95%, :Std Dev Lower 95%, :Std Dev Upper 95%
	),
	Output Table( "untitled 19.jmp" ),
	Remaining Columns( Drop All ),
	Sort by Column Property
);&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 27 Aug 2024 15:28:22 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/785983#M96907</guid>
      <dc:creator>Voizingu</dc:creator>
      <dc:date>2024-08-27T15:28:22Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/785995#M96908</link>
      <description>&lt;P&gt;Hello MRB3855,&lt;/P&gt;&lt;P&gt;You make an excellent point, I didn't want to put too much info in my first message to focus on my script problem, but in my initial code (that work for 2 levels), I set the &lt;SPAN&gt;equivalence limits as 5% of the range [LSL;USL].&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;This is of course an arbitrary value that I can change if necessary.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;It allows me to sift through hundreds+ of metrics and flag the "Not Equivalent" metrics from this criteria which are typically a dozen.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Then from this list I can run a thorough analysis:&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;- Analysis of Variance&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;- TOST with a proper range&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;- etc...&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;To you second point, If I understand well, you suggest to run the TOST platform for each metrics and pick the data and place into a table via Display Box()? If so, that is indeed a possible solution but I'd prefer run the math&amp;nbsp;&lt;/SPAN&gt;myself to understand the TOST principle and also save some processing time.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Hope it makes sense :)&lt;/img&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks for helping&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;-Voiz&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 15:38:53 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/785995#M96908</guid>
      <dc:creator>Voizingu</dc:creator>
      <dc:date>2024-08-27T15:38:53Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786008#M96909</link>
      <description>&lt;P&gt;Hello Mark,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Yes at first I thought of using the TOST platform and pick the stats with Display Box(), but I preferred the different approach to calculate each parameters individually to achieve the same results as the platform gives.&lt;/P&gt;&lt;P&gt;After the fact, it would maybe have been a faster approach than reinventing the wheel but I have now invested so much time into this, and I am so close of achieving it that I might as well finish what I started (the hard way), haha!&lt;/P&gt;&lt;P&gt;One benefit from this is that I now understand each step of the TOST method.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;-Voiz&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 15:45:54 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786008#M96909</guid>
      <dc:creator>Voizingu</dc:creator>
      <dc:date>2024-08-27T15:45:54Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786012#M96910</link>
      <description>&lt;P&gt;I would most likely use loops myself, but you can do it with some matrix operations. This script would require a rewrite to make it easier to read in my opinion (better named variables, utilizing Output table name, closing unnecessary tables and general cleanup)&lt;/P&gt;
&lt;LI-SPOILER&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here(1);

//Create table with random distribution (table 1)
dt = New Table("tabletest",
	Add Rows(5000),
	New Column("Product",
		Character,
		"Nominal",
		formula("Product " || Char(Random Integer(1, 4)))
	),
	New Column("Metric1", Numeric, "Continuous", formula(Random Normal(10, 1))),
	New Column("Metric2", Numeric, "Continuous", formula(Random Gamma(10, 1))),
	New Column("Metric3", Numeric, "Continuous", formula(Random Gamma(10, 2))), 
	
);
Column(dt, "Metric1") &amp;lt;&amp;lt; set property("spec limits", {LSL(5), USL(25), Show Limits(0)});
Column(dt, "Metric2") &amp;lt;&amp;lt; set property("spec limits", {LSL(0), USL(40), Show Limits(0)});
Column(dt, "Metric3") &amp;lt;&amp;lt; set property("spec limits", {LSL(5), USL(40), Show Limits(0)});


SplitBy = "Product";
Summarize(ColumnSplitBy = by(Column(SplitBy)));

MetricCols = dt &amp;lt;&amp;lt; Get Column Names(numeric, continuous, "string");

ColumnSplitByCombo = As List(NChooseK Matrix(N Items(ColumnSplitBy), 2));


//Create a combinaed datatable with stats (Table 2)
ow = dt &amp;lt;&amp;lt; Oneway(
	Y(Eval(MetricCols)),
	X(Eval(SplitBy)),
	Means and Std Dev(1),
	SendToReport(
		Dispatch({"Means and Std Deviations"}, "Std Dev Lower 95%", NumberColBox,
			{Visibility("Visible")}
		),
		Dispatch({"Means and Std Deviations"}, "Std Dev Upper 95%", NumberColBox,
			{Visibility("Visible")}
		)
	),
	Invisible
);

tb = Report(ow[1])[Outline Box("Means and Std Deviations"), Table Box(1)];
dt2 = tb &amp;lt;&amp;lt; Make Combined Data Table;
tb &amp;lt;&amp;lt; close window;

//Create a nested list with each pair of levels
Listdt3 = As List(NChooseK Matrix(N Items(ColumnSplitBy), 2));

mcols = N Items(MetricCols);
l = Repeat(Listdt3, mcols);
m = J(N Items(l) / mcols, mcols) :*&lt;/img&gt; (1::mcols);
mfinal = Sort Ascending(Shape(m, 1, N Items(l)));

dt3 = As Table(Matrix(l), &amp;lt;&amp;lt;column names({"x", "y"}));
dt3 &amp;lt;&amp;lt; New Column("metric", Character, Values(MetricCols[mfinal]));
dt3 &amp;lt;&amp;lt; New Column("first", character, &amp;lt;&amp;lt;set values(ColumnSplitBy[dt3:x &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; New Column("second", character, &amp;lt;&amp;lt;set values(ColumnSplitBy[dt3:y &amp;lt;&amp;lt; get values]));
dt3 &amp;lt;&amp;lt; New Column("R", Numeric, Ordinal, Values(1::N Items(l)));

dt4 = dt3 &amp;lt;&amp;lt; Stack(
	columns(:first, :second),
	Source Label Column("Label"),
	Stacked Data Column("Data"),
	"Non-stacked columns"n(Keep(:Metric, :R))
);

Close(dt3, no save);


dt4 &amp;lt;&amp;lt; Update(
	With(dt2),
	Match Columns(:metric = :Y, :Data = :Level)
);

dt_split = dt4 &amp;lt;&amp;lt; Split(
	Split By(:Label),
	Split(
		:Metric, :Data, :Number, :Mean, :Std Dev, :Std Err Mean, :Lower 95%, :Upper 95%,
		:Std Dev Lower 95%, :Std Dev Upper 95%
	),
	Output Table("untitled 19.jmp"),
	Remaining Columns(Drop All),
	Sort by Column Property
);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/LI-SPOILER&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_1-1724774273332.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67576i7A33F8F17FEAD03D/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_1-1724774273332.png" alt="jthi_1-1724774273332.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_2-1724774284315.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67577i906F6E675ADD899F/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_2-1724774284315.png" alt="jthi_2-1724774284315.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_0-1724774190734.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67575i9361F045B1E7C693/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_0-1724774190734.png" alt="jthi_0-1724774190734.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 15:58:24 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786012#M96910</guid>
      <dc:creator>jthi</dc:creator>
      <dc:date>2024-08-27T15:58:24Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786200#M96914</link>
      <description>&lt;P&gt;Hey Jarmo,&lt;/P&gt;&lt;P&gt;Thanks for your quick response.&lt;/P&gt;&lt;P&gt;This line is failing&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;m = J(N Items(l) / mcols, mcols)  (1::mcols);&lt;/PRE&gt;&lt;P&gt;Can you explain what it is intended to do?&lt;/P&gt;&lt;P&gt;I don't usually use Matrices, I tried to debug myself but couldn't...&lt;/P&gt;&lt;P&gt;Thanks for your help&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 18:05:04 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786200#M96914</guid>
      <dc:creator>Voizingu</dc:creator>
      <dc:date>2024-08-27T18:05:04Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786244#M96917</link>
      <description>&lt;P&gt;For some reason it is missing :*&lt;/img&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;m = J(N Items(l) / mcols, mcols) :*&lt;/img&gt; (1 :: mcols);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Purpose is to create a matrix like this&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_0-1724783213797.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67580i0884801B8E980405/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_0-1724783213797.png" alt="jthi_0-1724783213797.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;which you then convert to&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_1-1724783233014.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67581i12A5DD6C41673D7B/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_1-1724783233014.png" alt="jthi_1-1724783233014.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;using Shape.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Also go with the loops, they are generally much easier to read and understand than weird matrix "tricks".&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 18:27:58 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786244#M96917</guid>
      <dc:creator>jthi</dc:creator>
      <dc:date>2024-08-27T18:27:58Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786474#M96921</link>
      <description>&lt;P&gt;Hi Jarmo,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tested several versions of this line, adding special characters that could be lost in translation, but no...&amp;nbsp;&lt;/P&gt;&lt;P&gt;This line doesn't work on my end (I am using JMP Pro 17)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Voizingu_0-1724789449806.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67582iCA0F58EE4390064D/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Voizingu_0-1724789449806.png" alt="Voizingu_0-1724789449806.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;That's OK, this optimization using Matrix is really nice to have. As you said, using loops also works so I will go with that :)&lt;/img&gt;&lt;/P&gt;&lt;P&gt;Thanks again for taking the time to help me (once again)!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;:D&lt;/img&gt;&lt;/P&gt;&lt;P&gt;-Voiz&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 27 Aug 2024 20:13:25 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/786474#M96921</guid>
      <dc:creator>Voizingu</dc:creator>
      <dc:date>2024-08-27T20:13:25Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/787461#M96933</link>
      <description>&lt;P&gt;I have attached the part of code which breaks in community as a screenshot&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_0-1724823042717.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67591i893BF87D34613C98/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_0-1724823042717.png" alt="jthi_0-1724823042717.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;It is element-wise multiplication of matrices &lt;A href="https://www.jmp.com/support/help/en/18.0/#page/jmp/matrix-functions.shtml?os=win&amp;amp;source=application#ww2673612" target="_blank" rel="noopener"&gt;E Mult()&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;a href="https://community.jmp.com/t5/user/viewprofilepage/user-id/14379"&gt;@Ryan_Gilmore&lt;/a&gt; JMP community is eating :*&lt;/img&gt; (: * added space here)&lt;/P&gt;
&lt;P&gt;JSL code block:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;m = J(N Items(l) / mcols, mcols) :*&lt;/img&gt; (1::mcols);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Text:&lt;/P&gt;
&lt;P&gt;m = J(N Items(l) / mcols, mcols) :*&lt;/img&gt; (1::mcols);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Screenshot of while editing&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_1-1724823194621.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67592iAE71613F97DE2C86/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_1-1724823194621.png" alt="jthi_1-1724823194621.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Screenshot from Preview&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_2-1724823211799.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/67593i7EC174247935D6DC/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jthi_2-1724823211799.png" alt="jthi_2-1724823211799.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 28 Aug 2024 05:34:58 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/787461#M96933</guid>
      <dc:creator>jthi</dc:creator>
      <dc:date>2024-08-28T05:34:58Z</dc:date>
    </item>
    <item>
      <title>Re: [JSL] Script for Two-One Side T-Test on a large number of metrics</title>
      <link>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/787681#M96942</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.jmp.com/t5/user/viewprofilepage/user-id/54797"&gt;@Voizingu&lt;/a&gt;&amp;nbsp; &amp;nbsp;All said, it seems you have a solution that works for you. Excellent! However, so it doesn’t get lost, the confidence interval should be a 100(1-2alpha)% interval. I.e., if you want your type 1 error rate to be 5% then the interval used to judge equivalence should be a 90% confidence interval (not 95%). It is a&amp;nbsp;&lt;EM&gt;Two One Sided Test&lt;/EM&gt;…each side tested at alpha = 0.05. See attached,&lt;/P&gt;</description>
      <pubDate>Wed, 28 Aug 2024 10:38:11 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/JSL-Script-for-Two-One-Side-T-Test-on-a-large-number-of-metrics/m-p/787681#M96942</guid>
      <dc:creator>MRB3855</dc:creator>
      <dc:date>2024-08-28T10:38:11Z</dc:date>
    </item>
  </channel>
</rss>

