Riepilogo dei livelli categorialiVoglio ottenere un riepilogo dei valori di una colonna, utilizzandone un'altra come gruppo "Per".È come ciò che fa Summary() con N Categorie, ma voglio un elenco dei valori effettivi, non solo il loro numero.Prendiamo ad esempio questa tabella:

Voglio qualcosa del tipo:

Sto pensando che potrei fare qualcosa utilizzando la "Categoria" come sottogruppo in Riepilogo(), quindi Ricodifica e Combina colonne()?Qualche idea migliore o più intelligente?Ho curiosato un po' nella community e non sono riuscito a trovare nulla di analogo (sorprendentemente?). Forse un posto per l'uso degli array associativi?Questa tabella di esempio è piccola, la tabella su cui la eseguirò potrebbe contenere alcuni milioni di righe con centinaia di "livelli" per la colonna Gruppo.
Re: Riepilogo dei livelli categorialiSarebbe opportuno che contrassegnassi come Soluzione tutte le risposte che ti hanno fornito una risposta corretta, in modo che i futuri lettori possano vedere i diversi modi per risolvere il problema.Re: Riepilogo dei livelli categorialiGrazie ad entrambi per le soluzioni: ho finito per fare qualcosa con un array associativo.Lo scaricherò qui con la speranza che uno di questi tre approcci funzioni per la prossima persona che proverà a farlo:
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 << 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 << New Column(sum_colname, Character);
// dump the group col into a matrix for quicker access
sum_groupdat = dt_sum:Group << Get As Matrix();
main_groupdat = dt:Group << Get As Matrix();
For( ri = 1, ri <= 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 << 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 <= N Items( keys ), ki++,
charkeys[ki] = Char( keys[ki] );
);
,
charkeys = keys
);<BR /> // stuff all the items together and dump it into this row
valstr = Concat Items( charkeys, "," );
Column( dt_sum, sum_colname )[ri] = valstr;
);
Re: Riepilogo dei livelli categorialiOra vedo che Jim ha già presentato una soluzione.
Ecco un approccio diverso che utilizza la tabulazione e la combinazione di colonne (colonna a risposta multipla) che si spera funzioni anche sull'intero set di dati.
// Groups is the example table with 2 nominal columns
DT_GroupCategory = Data Table( "Groups" );
// creates a cross table
Tab_DT_GroupCategory = DT_GroupCategory << Tabulate(
Add Table(
Column Table( Grouping Columns( :Category ) ),
Row Table( Grouping Columns( :Group ) )
)
);
// make data table from it
DT_GroupCategory_CrossTab = Tab_DT_GroupCategory << Make Into Data Table;
DT_GroupCategory_CrossTab << Add Multiple Columns( "N Categories", 1, after( 1 ), Numeric );
Names_DT_GroupCategory_CrossTab = DT_GroupCategory_CrossTab << 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<=N Items( Names_DT_GroupCategory_CrossTab ), i++,
Column( DT_GroupCategory_CrossTab, i ) << Data Type( "Character" );
For( j=1, j<=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 -> Utilities -> Combine Columns
DT_GroupCategory_CrossTab << 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" ) << Formula( (Length( :Name( "Values(Category)" ) ) + 1) / 2 );
Tab_DT_GroupCategory << Close Window;

Re: Riepilogo dei livelli categorialiPenso che il modo per iniziare sia dividere la tabella dei dati e poi lavorare da lì.Di seguito è riportato un semplice script che ho scritto per ottenere i risultati desiderati.Se la tua necessità è farlo in modo interattivo, segui semplicemente i passaggi nello script
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 << data type( character );
// Split the columns
dtSplit = dt << Split( Split By( :Category ), Split( :Group ), Group( :Group ), Sort by Column Property );
// Change the data type back
dt:Group << data type( numeric );
dtSplit:Group << data type( numeric );
// Convert all of the non blank entries to the value of the column name
For( i = 2, i <= N Cols( dtSplit ), i++,
theRows = dtSplit << get rows where( As Column( dtsplit, i ) != "" );
If( N Rows( theRows ) > 0,
Column( dtSplit, i )[theRows] = Column( dtsplit, i ) << get name
);
);
// get all of the character column names
namesList = dtSplit << get column names( character, string );
// Create the combined column
dtSplit << Combine Columns(
delimiter( "," ),
Columns( :a, :b, :c, :d, :X, :y, :z ),
Column Name( "Values (Category)" )
);
// Count the number of combined values
dtSplit << 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)") << delete property(formula);
// delete the unnecessary columns
dtSplit << delete columns( namesList );