Да предположим, че имам някои table
(или < href="http://www.mathworks.com/help/stats/dataset.html" rel="nofollow">dataset
) обект A
, който включва някакъв фактор X
(имащ n отделни стойности или „нива“) сред своите променливи. Да предположим също, че имам някаква персонализирана функция за агрегиране agg
, която приема като вход поредица от редове и връща едно обобщено число (известно още като "агрегат") като изход.
Пример за изключително често срещана операция в статистическия анализ на данни би било да се групират редовете на A
според стойността на фактора X
и да се приложи agg
към масивите, състоящи се от редовете в групата. Резултатът от такава операция трябва да бъде нов table
(или dataset
, в зависимост от класа на A
), с n редове и две променливи. Първата от тези променливи трябва да бъде наречена X
и трябва да съдържа n отделните стойности на фактора X
в A
, а втората трябва да има някакво подходящо (за предпочитане зададено от потребителя) име и трябва да съдържа резултатът от прилагането на agg
към групите редове за съответните X
нива.
Както казах, това е много стандартна операция за изпълнение на структури от данни като обектите table
и dataset
на MATLAB, така че очаквах да има вграден начин да го направя, но не го намирам.
Например, нека 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'});
Освен това нека X
е TrafficLight
и 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'})
Надявам се, че вграденото решение е по-стабилно за, например, различни класове стойности за променливата X
и т.н.