如何将聚合函数应用于表(或数据集)行组?

时间:2014-02-07 00:11:04

标签: matlab aggregate accumarray matlab-table

假设我有一些table(或dataset)对象A,其中包含一些因子X n 不同的值,或者“其变量中的“等级”。还假设我有一些自定义聚合函数agg,它将一系列行作为输入,并返回一个摘要号(也称为“聚合”)作为输出。

统计数据分析中常见操作的一个示例是根据A因子的值对X行进行分组,并应用{ {1}}到由组中的行组成的数组。此类操作的结果应该是新的agg(或table,具体取决于dataset的类), n 行和两个变量。这些变量中的第一个应该命名为A,并且应该包含XX因子的 n 不同值,第二个应该有一些适当的(最好是用户指定的)名称,并且应包含将A应用于相应agg级别的行组的结果。

正如我所说,这是对MATLAB的Xtable对象等数据结构执行的非常标准的操作,所以我期待有一种内置的方法来执行它,但我找不到它。


例如,让dataset定义如下:

A

另外,让% "data" table A = cell2table({ 'even', 'red', 'spades', 38, 0.9837; 'even', 'red', 'hearts', 19, 0.5695; 'even', 'red', 'diamonds', 89, 0.2629; 'even', 'red', 'diamonds', 98, 0.3578; 'even', 'red', 'diamonds', 92, 0.2596; 'even', 'red', 'diamonds', 69, 0.5751; 'even', 'red', 'diamonds', 77, 0.6318; 'even', 'yellow', 'clubs', 22, 0.6917; 'even', 'green', 'spades', 35, 0.6674; 'even', 'green', 'hearts', 67, 0.7896; 'even', 'green', 'hearts', 49, 0.5025; 'even', 'green', 'hearts', 64, 0.5318; 'odd', 'red', 'spades', 22, 0.5587; 'odd', 'red', 'hearts', 51, 0.9122; 'odd', 'red', 'diamonds', 74, 0.3343; 'odd', 'red', 'diamonds', 69, 0.2911; 'odd', 'yellow', 'spades', 33, 0.2653; 'odd', 'yellow', 'spades', 38, 0.2549; 'odd', 'yellow', 'diamonds', 1, 0.2064; 'odd', 'yellow', 'diamonds', 25, 0.8257; 'odd', 'green', 'spades', 64, 0.4348; 'odd', 'green', 'hearts', 59, 0.8644; 'odd', 'green', 'hearts', 4, 0.6374; 'odd', 'green', 'hearts', 11, 0.3354 }, 'VariableNames', ... {'Parity', 'TrafficLight', 'Suit', 'order', 'prevalence'}); XTrafficLight

agg

(当然,我在这里使用此agg = @(t) size(t, 1); 只是为了让示例尽可能简单。实际上,agg将不那么简单。)

我想到的典型agg函数通常将输入参数(按某种顺序)作为聚合函数,计算聚合的输出中列的名称,group_aggregate(或table),以及要分组的一个或多个变量的名称。因此,在这个例子中,对这样一个函数及其输出的调用看起来像这样

dataset
顺便说一句,为了得到上面的结果,我想起了这个绝望的小野兽:

>> group_aggregate(agg, 'nrows', A, {'TrafficLight'})

ans =

    TrafficLight    nrows
    ____________    _____

    'green'          8   
    'red'           11   
    'yellow'         5   

我希望内置解决方案对>> tmp = cellfun(@(s) {s agg(A(strcmp(A.TrafficLight, s), :))}, ... unique(A.TrafficLight), 'un', 0); >> cell2table(cat(1, tmp{:}), 'VariableNames', {'TrafficLight' 'nrows'}) 变量的不同类值等更加健壮。

2 个答案:

答案 0 :(得分:2)

我不知道只是为了这个目的的table方法,但是为了聚合,请查看accumarray

>> [lights,ia,ic]=unique(A.TrafficLight);
>> nrows = accumarray(ic,1);
>> cell2table([lights num2cell(nrows)],'VariableNames', {'TrafficLight' 'nrows'})
ans = 
    TrafficLight    nrows
    ____________    _____
    'green'          8   
    'red'           11   
    'yellow'         5   

答案 1 :(得分:0)

我知道问题是1岁......

我使用了一种不同的方式。我用tabulate http://www.mathworks.com/help/stats/tabulate.html?s_tid=gn_loc_drop

我还有一个旧版本的Matlab,因此我使用了数据集。在这种情况下(但我认为它也适用于'table'),您的代码将是:

TrafficLight_stats=tabulate(A.TrafficLight);
Agg_table=mat2dataset(TrafficLight_stats,'VarNames',{'TrafficLight','nrows','Perc'});

Agg_table = 

TrafficLight    nrows       Perc         
'red'           [11]        [45.8333]
'yellow'        [ 5]        [20.8333]
'green'         [ 8]        [33.3333]