1

I have a table T as below:

T = table({'A';'A';'B';'B';'B';'B';'C';'C';'D';'D'},...
          {'xd';'z';'x';'y';'z';'w';'x';'wh';'z';'w'},...
          [4;2;4;1;2;5;2;1;1;5], ...
          'VariableNames', {'memberId', 'productId','Rating'});
T = 
memberId    productId    Rating
________    _________    ______
'A'         'xd'         4     
'A'         'z'          2     
'B'         'x'          4     
'B'         'y'          1     
'B'         'z'          2     
'B'         'w'          5     
'C'         'x'          2     
'C'         'wh'         1     
'D'         'z'          1     
'D'         'w'          5 

I need to index it by memberId and productId so the result is:

A: {'xd'  'z'}
B: {'x'  'y' 'z' 'w'}
C: {'x' 'wh'}
.......
EBH
  • 10,350
  • 3
  • 34
  • 59
Eli
  • 83
  • 8
  • isn't the letter already the index for that? – Finn Aug 10 '16 at 10:17
  • A: {'xd' 'z'} contain a index offer to memberId 'A' that rate to 'xd' and 'z' – Eli Aug 10 '16 at 10:22
  • ok i feel like i have an idea what the result should be. unfortunately it cant be as you want it to because `{'xd' 'z'}` will end up being `{'xdz'}`. All You can make is the Rownumbers, a logical index with true and false for evey row or a cell array in a table `{'xd'};{ 'z'}` – Finn Aug 10 '16 at 10:37

1 Answers1

1

You can use categorical arrays and a structure to do this:

% convert to categorical arrays
T.memberId = categorical(T.memberId);
T.productId = categorical(T.productId);
% cross-tabulate memberId vs. productId
cross_T = crosstab(T.memberId,T.productId);
% a function to return the productId for all 1 in row
productId = categories(T.productId).';
row = @(x) productId(logical(cross_T(x,:)));
% preform on all rows
rBy_c = arrayfun(row,1:size(cross_T,1),'UniformOutput',false).';
% convert to structure for readability
s = cell2struct(rBy_c,categories(T.memberId))

To get the output (s):

A: {'xd'  'z'}
B: {'w'  'x'  'y'  'z'}
C: {'wh'  'x'}
D: {'w'  'z'}
EBH
  • 10,350
  • 3
  • 34
  • 59
  • hello my friend. I have a question. can you help me? – Eli Oct 01 '16 at 08:45
  • Maybe... Post it, and I will answer if I can :) – EBH Oct 01 '16 at 17:26
  • Thank you. I answered It in this post: http://stackoverflow.com/questions/39722872/adding-multiple-rows-of-a-table-to-another-table – Eli Oct 01 '16 at 17:38
  • Hi again . Is it possible at the bottom of the cells, the index of products in productId save it? – Eli Oct 24 '16 at 07:46
  • I can with this code find index of products : [~,c] = ismember(s.(UserId{1}),upIDs) that upIDs contains index of all products. and with this code, I cat convert double to cell array : rBy_c2 = arrayfun(@num2str, c , 'Uniform', false) . so I want save rBy_c2 into s with this Code but in this step program give error to me : s.(UserId{k}) {2,:} = c . can you right this step for me? – Eli Oct 24 '16 at 12:29
  • Use this to convert `c` to cells: `rBy_c2 = num2cell(c);` and then write this to add it to `s`: `s.(UserId{k})(2,:) = rBy_c2`. For further explanations, please kindly post a new question. Note that in your comment you creates `rBy_c2` but never use it... – EBH Oct 24 '16 at 18:13
  • how can access to size of 's' and size of any cell in it? – Eli Oct 25 '16 at 06:57
  • ok thank you. but this question related with this post , I asked there. I'm sorry – Eli Oct 25 '16 at 06:58
  • 1
    structSize = length(fieldnames(s)) . I find it. thank you. – Eli Oct 25 '16 at 07:10
  • For the size of the cells in `s` use `size(s.(UserId{k}))`. – EBH Oct 25 '16 at 08:19