分类级别摘要我想获得一列值的摘要,将另一列用作“按”组。这就像 Summary() 对 N 个类别所做的那样,但我想要一个实际值的列表,而不仅仅是它们的数量。例如拿这张表:

我想要这样的东西:

我在想我可以通过使用“类别”作为 Summary() 中的子组来做一些事情,然后重新编码并合并 Columns()?有什么更好或更聪明的想法吗?我在社区里闲逛了一下,找不到任何类似的东西(令人惊讶的是?)也许是一个使用关联数组的地方?这个示例表很小,我将在其上运行的表可能有几百万行,其中 Group 列有数百个“级别”。
回复:分类级别摘要您最好将所有为您提供正确答案的回复标记为解决方案,以便未来的读者可以看到解决问题的不同方法。回复:分类级别摘要感谢这两个解决方案 - 我最终用关联数组做了一些事情。我将把它放在这里,希望这三种方法中的一种对下一个尝试这样做的人有用:
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;
);
回复:分类级别摘要我现在看到 Jim 已经提出了解决方案。
这是一种使用制表和组合列(多响应列)的不同方法,希望它也适用于完整的数据集。
// 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;

回复:分类级别摘要我认为开始的方法是对数据表进行拆分,然后从那里开始工作。下面是我编写的一个简单脚本,目的是让您获得想要的结果。如果您需要以交互方式执行此操作,只需按照脚本中的步骤操作
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 );