<?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: Summary of categorical levels in Discussions</title>
    <link>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/242234#M47827</link>
    <description>&lt;P&gt;I see now Jim has already presented a solution.&lt;/P&gt;&lt;P&gt;Here's a different approach using Tabulate and Combine Columns (Multiple Response Column) that hopefully works also on the full data set.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;// Groups is the example table with 2 nominal columns
DT_GroupCategory = Data Table( "Groups" );

// creates a cross table
Tab_DT_GroupCategory = DT_GroupCategory &amp;lt;&amp;lt; Tabulate(
	Add Table(
		Column Table( Grouping Columns( :Category ) ),
		Row Table( Grouping Columns( :Group ) )
	)
);

// make data table from it 
DT_GroupCategory_CrossTab = Tab_DT_GroupCategory &amp;lt;&amp;lt; Make Into Data Table;
DT_GroupCategory_CrossTab &amp;lt;&amp;lt; Add Multiple Columns( "N Categories", 1, after( 1 ), Numeric );
Names_DT_GroupCategory_CrossTab = DT_GroupCategory_CrossTab &amp;lt;&amp;lt; Get Column Names;

// replace 0 by missing and everything else by column name (probably not the most efficient way to do this)
For( i=3, i&amp;lt;=N Items( Names_DT_GroupCategory_CrossTab ), i++,
	Column( DT_GroupCategory_CrossTab, i ) &amp;lt;&amp;lt; Data Type( "Character" );
	For( j=1, j&amp;lt;=N Rows( DT_GroupCategory_CrossTab ), j++,
		If( Column( DT_GroupCategory_CrossTab, i )[j] == "0",
			Column( DT_GroupCategory_CrossTab, i )[j] = "",
			Column( DT_GroupCategory_CrossTab, i )[j] = Char( Names_DT_GroupCategory_CrossTab[i] );
		)
	)
);

// make multiple response column with Cols -&amp;gt; Utilities -&amp;gt; Combine Columns
DT_GroupCategory_CrossTab &amp;lt;&amp;lt; Combine Columns(
	delimiter( "," ),
	Columns( 2::N Items( Names_DT_GroupCategory_CrossTab ) ),
	Selected Columns are Indicator Columns( 0 ),
	Column Name( "Values(Category)" )
);

// add formula to get N Categories. +1 is added for one less comma, then div by 2 to get number of categories
Column( DT_GroupCategory_CrossTab, "N Categories" ) &amp;lt;&amp;lt; Formula( (Length( :Name( "Values(Category)" ) ) + 1) / 2 );

Tab_DT_GroupCategory &amp;lt;&amp;lt; Close Window;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Categories.png" style="width: 875px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/21095iD42D6191E0E861C2/image-size/large?v=v2&amp;amp;px=999" role="button" title="Categories.png" alt="Categories.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
    <pubDate>Wed, 22 Jan 2020 00:59:20 GMT</pubDate>
    <dc:creator>gerd</dc:creator>
    <dc:date>2020-01-22T00:59:20Z</dc:date>
    <item>
      <title>Summary of categorical levels</title>
      <link>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/242207#M47822</link>
      <description>&lt;P&gt;I want to get a summary of the values of a column, using another as a "By" group.&amp;nbsp; It's like what Summary() does with N Categories, but I want a list of the actual values, not just the number of them.&amp;nbsp; For example take this table:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="klk_0-1579640769084.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/21092iF5651600F1060792/image-size/medium?v=v2&amp;amp;px=400" role="button" title="klk_0-1579640769084.png" alt="klk_0-1579640769084.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;I want something like:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="klk_1-1579640899959.png" style="width: 400px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/21093i8E97ED9E28128CE3/image-size/medium?v=v2&amp;amp;px=400" role="button" title="klk_1-1579640899959.png" alt="klk_1-1579640899959.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm thinking I could do something with using the 'Category' as a subgroup in Summary(), then Recode and Combine Columns()?&amp;nbsp; Any better or more clever ideas?&amp;nbsp; I poked around the community a bit and couldn't find anything analgous (suprisingly?)&amp;nbsp; Maybe a place for use of Associative Arrays?&amp;nbsp; This example table is tiny, the table I will be running this on could be a few million rows with hundreds of "levels" for the Group column.&lt;/P&gt;</description>
      <pubDate>Tue, 21 Jan 2020 21:24:16 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/242207#M47822</guid>
      <dc:creator>klk</dc:creator>
      <dc:date>2020-01-21T21:24:16Z</dc:date>
    </item>
    <item>
      <title>Re: Summary of categorical levels</title>
      <link>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/242224#M47824</link>
      <description>&lt;P&gt;I think the way to start is to do a split on the data table, and then to work from there.&amp;nbsp; Below is a simple script that I wrote to get you the results you want.&amp;nbsp; If your need is to do this interactively, just follow the steps in the script&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="split.PNG" style="width: 544px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/21094i8F7FB7A1AB8E9E0E/image-size/large?v=v2&amp;amp;px=999" role="button" title="split.PNG" alt="split.PNG" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here( 1 );

// Create the beginning table
dt = New Table( "Example",
	Add Rows( 11 ),
	New Column( "Group",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8] )
	),
	New Column( "Category",
		Character,
		"Nominal",
		Set Values( {"A", "A", "B", "A", "D", "X", "Y", "Z", "A", "B", "C"} )
	)
);

// Change the group column to character so
// split columns are blanks and not missing values
dt:Group &amp;lt;&amp;lt; data type( character );

// Split the columns
dtSplit = dt &amp;lt;&amp;lt; Split( Split By( :Category ), Split( :Group ), Group( :Group ), Sort by Column Property );

// Change the data type back
dt:Group &amp;lt;&amp;lt; data type( numeric );
dtSplit:Group &amp;lt;&amp;lt; data type( numeric );

// Convert all of the non blank entries to the value of the column name
For( i = 2, i &amp;lt;= N Cols( dtSplit ), i++,
	theRows = dtSplit &amp;lt;&amp;lt; get rows where( As Column( dtsplit, i ) != "" );
	If( N Rows( theRows ) &amp;gt; 0,
		Column( dtSplit, i )[theRows] = Column( dtsplit, i ) &amp;lt;&amp;lt; get name
	);
);

// get all of the character column names
namesList = dtSplit &amp;lt;&amp;lt; get column names( character, string );

// Create the combined column
dtSplit &amp;lt;&amp;lt; Combine Columns(
	delimiter( "," ),
	Columns( :a, :b, :c, :d, :X, :y, :z ),
	Column Name( "Values (Category)" )
);

// Count the number of combined values
dtSplit &amp;lt;&amp;lt; New Column( "N Categories (Category)",
	Numeric,
	"Continuous",
	Format( "Best", 12 ),
	Formula(
		count = 1;
		While( Word( count, :Name( "Values (Category)" ), "," ) != "", count++ );
		count = count - 1;
	)
);

// get rid of the formula
dtSplit:Name("N Categories (Category)") &amp;lt;&amp;lt; delete property(formula);

// delete the unnecessary columns
dtSplit &amp;lt;&amp;lt; delete columns( namesList );&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 21 Jan 2020 22:58:50 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/242224#M47824</guid>
      <dc:creator>txnelson</dc:creator>
      <dc:date>2020-01-21T22:58:50Z</dc:date>
    </item>
    <item>
      <title>Re: Summary of categorical levels</title>
      <link>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/242234#M47827</link>
      <description>&lt;P&gt;I see now Jim has already presented a solution.&lt;/P&gt;&lt;P&gt;Here's a different approach using Tabulate and Combine Columns (Multiple Response Column) that hopefully works also on the full data set.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;// Groups is the example table with 2 nominal columns
DT_GroupCategory = Data Table( "Groups" );

// creates a cross table
Tab_DT_GroupCategory = DT_GroupCategory &amp;lt;&amp;lt; Tabulate(
	Add Table(
		Column Table( Grouping Columns( :Category ) ),
		Row Table( Grouping Columns( :Group ) )
	)
);

// make data table from it 
DT_GroupCategory_CrossTab = Tab_DT_GroupCategory &amp;lt;&amp;lt; Make Into Data Table;
DT_GroupCategory_CrossTab &amp;lt;&amp;lt; Add Multiple Columns( "N Categories", 1, after( 1 ), Numeric );
Names_DT_GroupCategory_CrossTab = DT_GroupCategory_CrossTab &amp;lt;&amp;lt; Get Column Names;

// replace 0 by missing and everything else by column name (probably not the most efficient way to do this)
For( i=3, i&amp;lt;=N Items( Names_DT_GroupCategory_CrossTab ), i++,
	Column( DT_GroupCategory_CrossTab, i ) &amp;lt;&amp;lt; Data Type( "Character" );
	For( j=1, j&amp;lt;=N Rows( DT_GroupCategory_CrossTab ), j++,
		If( Column( DT_GroupCategory_CrossTab, i )[j] == "0",
			Column( DT_GroupCategory_CrossTab, i )[j] = "",
			Column( DT_GroupCategory_CrossTab, i )[j] = Char( Names_DT_GroupCategory_CrossTab[i] );
		)
	)
);

// make multiple response column with Cols -&amp;gt; Utilities -&amp;gt; Combine Columns
DT_GroupCategory_CrossTab &amp;lt;&amp;lt; Combine Columns(
	delimiter( "," ),
	Columns( 2::N Items( Names_DT_GroupCategory_CrossTab ) ),
	Selected Columns are Indicator Columns( 0 ),
	Column Name( "Values(Category)" )
);

// add formula to get N Categories. +1 is added for one less comma, then div by 2 to get number of categories
Column( DT_GroupCategory_CrossTab, "N Categories" ) &amp;lt;&amp;lt; Formula( (Length( :Name( "Values(Category)" ) ) + 1) / 2 );

Tab_DT_GroupCategory &amp;lt;&amp;lt; Close Window;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Categories.png" style="width: 875px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/21095iD42D6191E0E861C2/image-size/large?v=v2&amp;amp;px=999" role="button" title="Categories.png" alt="Categories.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 22 Jan 2020 00:59:20 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/242234#M47827</guid>
      <dc:creator>gerd</dc:creator>
      <dc:date>2020-01-22T00:59:20Z</dc:date>
    </item>
    <item>
      <title>Re: Summary of categorical levels</title>
      <link>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/243125#M47986</link>
      <description>&lt;P&gt;Thanks to both for the solutions - I ended up doing something with an associative array.&amp;nbsp; I'll dump that in here with the hopes that one of these three approaches works for the next person trying to do this:&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 );

// Create the beginning table
dt = New Table( "Example",
	Add Rows( 11 ),
	New Column( "Group",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values( [1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8] )
	),
	New Column( "Category",
		Character,
		"Nominal",
		Set Values( {"A", "A", "B", "A", "D", "X", "Y", "Z", "A", "B", "C"} )
	)
);

// let Summary do N Categories() for us
dt_sum = dt &amp;lt;&amp;lt; Summary( Group( :Group ), N Categories( Category ) );

// the name of the column for which we want a list of the categories
category_col = "Category";
sum_colname = "Value List("|| category_col || ")";

// new col in the summary table to hold the list of values
dt_sum &amp;lt;&amp;lt; New Column(sum_colname, Character);

// dump the group col into a matrix for quicker access
sum_groupdat = dt_sum:Group &amp;lt;&amp;lt; Get As Matrix();
main_groupdat = dt:Group &amp;lt;&amp;lt; Get As Matrix();

For( ri = 1, ri &amp;lt;= N Rows( dt_sum ), ri++, 
	// rows in main table that match the 'group by' col
	inds = Loc( main_groupdat, sum_groupdat[ri] );
	
	tmpaa = Associative Array( Column( dt, category_col )[inds] );
	keys = tmpaa &amp;lt;&amp;lt; Get Keys();
	// if the category_col is numeric, need to convert the numbers to chars!
	If( Is Number( keys[1] ),
		charkeys = {};
		For( ki = 1, ki &amp;lt;= N Items( keys ), ki++,
			charkeys[ki] = Char( keys[ki] );
		);
	,
		charkeys = keys
	);&lt;BR /&gt;	// stuff all the items together and dump it into this row
	valstr = Concat Items( charkeys, "," );
	Column( dt_sum, sum_colname )[ri] = valstr;
);&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 28 Jan 2020 01:24:26 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/243125#M47986</guid>
      <dc:creator>klk</dc:creator>
      <dc:date>2020-01-28T01:24:26Z</dc:date>
    </item>
    <item>
      <title>Re: Summary of categorical levels</title>
      <link>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/243126#M47987</link>
      <description>It would be appropriate for you to mark all of the responses that provided you with a correct answer as a Solution, so that future readers can see the different ways to solve the problem.</description>
      <pubDate>Tue, 28 Jan 2020 01:27:54 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Summary-of-categorical-levels/m-p/243126#M47987</guid>
      <dc:creator>txnelson</dc:creator>
      <dc:date>2020-01-28T01:27:54Z</dc:date>
    </item>
  </channel>
</rss>

