[g,ig]=findgroups(data.names);
b=splitapply(@(x) {maxk(x,10)},data.age,g);
b contains the k oldest elements for each group...you'll have to use an m-file function to return the optional second index from maxk to locate the position of the N individuals in the group.
>> [cellstr(ig) b]
ans =
7×2 cell array
{'Ben' } {10×1 double}
{'Billy'} { 4×1 double}
{'Happy'} { 4×1 double}
{'Jenny'} {10×1 double}
{'Joe' } { 8×1 double}
{'Kate' } {10×1 double}
{'Smith'} {10×1 double}
>>
ADDENDUM: The indexing would look something like--
function [mx,ix]=getmaxk(x,n)
[mx,ix]=maxk(x,n);
mx={mx};
ix={ix};
end
fnmaxk=@(x) getmaxk(x,10);
[b,ib]=splitapply(fnmaxk,data.age,g);
ADDENDUM SECOND:
OK, it's not so bad after all -- have to do it explicitly right now; seems like a good candidate for an enhancement to splitapply() to have available as an auxiliary variable.
Start with
function sq=getmaxkgrp(x,v)
n=10;
[mx,ix]=maxk(x,n);
sq=v(ix);
end
which has the 10 value hardcoded; you can use the indirect method illustrated above to be able to change the number for which you're looking.
Then, as suggested, augment the table with
data.seq=[1:height(data)].';
ix=splitapply(@(x1,x2) {getmaxkgrp(x1,x2)},data.age,data.seq,g);
tmaxk=(cellfun(@(ix) data(ix,1:end-1),ix,'uni',0));
tmaxk=vertcat(tmaxk{:});
Above results in--
>> tmaxk =
56×3 table
names age pet
_____ ___ ____
Ben 31 fish
Ben 31 bird
Ben 31 bird
Ben 31 bird
Ben 31 fish
Ben 21 dog
Ben 21 fish
Ben 21 dog
Ben 21 fish
Ben 17 dog
Billy 30 fish
Billy 30 bird
Billy 30 fish
Billy 30 bird
Happy 31 bird
Happy 31 cat
Happy 31 bird
Happy 31 cat
Jenny 30 cat
Jenny 30 dog
Jenny 30 dog
Jenny 30 fish
Jenny 30 dog
Jenny 30 fish
Jenny 30 dog
Jenny 30 fish
Jenny 30 cat
Jenny 30 dog
Joe 79 dog
Joe 79 dog
Joe 21 dog
Joe 20 cat
Joe 19 cat
Joe 18 bird
Joe 15 cat
Joe 15 cat
Kate 60 fish
Kate 60 fish
Kate 60 fish
Kate 51 fish
Kate 51 fish
Kate 51 fish
Kate 51 fish
Kate 50 bird
Kate 50 dog
Kate 50 bird
Smith 38 fish
Smith 38 bird
Smith 38 fish
Smith 38 bird
Smith 38 bird
Smith 38 fish
Smith 30 bird
Smith 29 bird
Smith 29 cat
Smith 29 cat
>>
I didn't test it extensively but I believe it will have returned the correct values. Using a smaller value for N would make that part much easier; left as "Exercise for Student!" :)
Best Answer