1

I have a table as below : (This is a few lines from my table)

T = table({'A';'A';'A';'B';'B';'B';'C';'C';'C';'C'}, {'x';'y';'z';'x';'w';'t';'z';'x';'t';'o'},[5;1;2;2;4;2;2;5;4;1], ...
      'VariableNames', {'memberId', 'productId','Rating'});

T:

A  x  5
A  y  1
Z  z  2
B  x  2
B  w  4
B  t  2
C  z  2
C  x  5
C  t  4
C  o  1
C  u  3
D  r  1
D  t  2
D  w  5
.
.
.
.

I need to take the user A then Create a table like Previous table (Table T) and All rows are related to the user A to enter that table.At this point in the table are the following lines:

A  x  5
A  y  1
A  z  2

Next, consider products related to this user i.e x,y,z . then All lines that contain x and then y and z are adding to the table. At this point in the table are the following lines:

A  x  5
A  y  1
A  z  2
B  x  2
C  z  2
C  x  5

Then, other users have been added to the table to consider i.e B,C . Then The same thing was done for the first user (A) is done for this user (Respectively for B then C). This is done so that the required number of rows add in the table. Here, for example, 8 rows is required. i.e The end result is as follows:

A  x  5
A  y  1
A  z  2
B  x  2
C  z  2
C  x  5
B  w  4
B  t  2

i.e when work is finished the requested number of rows in the second table row to be imported.

I would be grateful if any body help me in this regard.

EBH
  • 10,350
  • 3
  • 34
  • 59
Eli
  • 83
  • 8
  • 1
    so all entries from the orginal table will be there only in a different order? – Finn Sep 27 '16 at 11:02
  • no. I want to do processing on the final table. My original table is very large and represents a graph. I choose this part of the graph, and I want to do some processing on it – Eli Sep 27 '16 at 11:06
  • 2
    I believe Finn's question is are all entries from the original table present in the new table - just the ordering has changed. – GameOfThrows Sep 27 '16 at 11:10
  • so you will input the users that will be used or this will run until there is no connection between the remaining users and their productIds? – Finn Sep 27 '16 at 11:10
  • no It is not ordering. you suppose my original table has 100 rows and I want 20 rows from it.(for example). – Eli Sep 27 '16 at 11:19
  • no I will run until the final table, to have the desired number of rows. ( In question I said original table has 10 row and second table will have 8 row. I said this example because The reader, understand my question Reduction) – Eli Sep 27 '16 at 11:24
  • Do you understand my question? – Eli Sep 27 '16 at 11:27
  • is the order in the final table of importance? – Finn Sep 27 '16 at 13:25
  • I can say that is not important order at the final table. but order in x , y , z is important or order in B and C ,...... – Eli Sep 27 '16 at 13:33
  • but Even if you can solve this problem that not order in x,y,z , .....I am grateful. – Eli Sep 27 '16 at 13:43
  • i still dont get it if you do tose steps for A,B and C you will end up with all lines. There are only 8 because you only did this for A and B. So do you give A and B or how does the procedure start and end? – Finn Sep 27 '16 at 15:43
  • If the algorithm will continue to end, all rows in the main table are included. But we have only a certain number of rows (8 rows) need. The final condition is that the eight row of the original table is entered to second table. – Eli Sep 27 '16 at 16:06
  • I should have gone steps somewhere that a certain number of rows from original table are imported into the second table. It is important. – Eli Sep 27 '16 at 16:15
  • What happens if the next set of rows to be added is greater than the rows left to be added. Say there are 7 rows for user A, and now you want to add 5 rows for products x,y,z, but you have only one open slot for a new row - which row you pick? or maybe you leave it empty? – EBH Oct 01 '16 at 20:29

1 Answers1

1

Here is a way for doing what you ask for (though some cases are not well defined in your question):

% I added user 'D' for the scenario of an unconnected node
T = table({'A';'A';'A';'B';'B';'B';'C';'C';'C';'C';'D';'D';'D';'D'},...
    {'x';'y';'z';'x';'w';'t';'z';'x';'t';'o';'q';'p';'f';'v'},...
    [5;1;2;2;4;2;2;5;4;1;4;5;2;1], ...
    'VariableNames', {'memberId', 'productId','Rating'});
% initial preparations:
rows_limit = 8;
first_user = 'B'; % this is just for readability
newT = table(cell(rows_limit,1),cell(rows_limit,1),zeros(rows_limit,1),...
    'VariableNames',{'memberId', 'productId','Rating'});
% We need an index vector so we won't add the same row twice:
added = false(height(T),1);
row_count = 1;
users_list = {first_user};

% now we start adding rows to newT until it's full: 
while row_count<rows_limit
    while numel(users_list)>=1
        % get all the user's rows
        next_to_add = strcmp(T.memberId,users_list{1}) & ~added;
        % if this user has any rows to be added:
        if sum(next_to_add)>0
            % if there's enough empty rows in newT add them to it:
            if  sum(next_to_add) <= rows_limit-row_count+1
                newT(row_count:row_count+sum(next_to_add)-1,:) = T(next_to_add,:)
                % and update the index vector:
                added = added | strcmp(T.memberId,users_list{1});
            else
                % otherwise - fill the empty rows and quit the loop:
                if row_count <= rows_limit
                    end_to_add = find(next_to_add,rows_limit-row_count+1);
                    newT(row_count:rows_limit,:) = T(end_to_add,:)
                end
                row_count = rows_limit+1; % to exit the outer loop
                break
            end
            row_count = row_count+sum(next_to_add);

            % Add related products:
            % ====================
            % save the first new user to be addaed by related products:
            last_user_row = row_count;
            % get all the products we already added to newT:
            products = unique(newT.productId(1:row_count-1),'stable');
            % although we want only the last user products, because we add all the
            % products the before, our index vector ('added') will eliminate them
            for p = 1:numel(products)
                % get all the product's rows
                next_to_add = strcmp(T.productId,products{p}) & ~added;
                % if there's enough empty rows in newT add them to it:
                if sum(next_to_add)>0
                    if sum(next_to_add) <= rows_limit-row_count+1
                        newT(row_count:row_count+sum(next_to_add)-1,:) = T(next_to_add,:);
                        % and update the index vector:
                        added = added | strcmp(T.productId,products{p});
                    else
                        % otherwise - fill the empty rows and quit the loop:
                        if row_count <= rows_limit
                            end_to_add = find(next_to_add,rows_limit-row_count+1);
                            newT(row_count:rows_limit,:) = T(end_to_add,:);
                        end
                        row_count = rows_limit+1; % to exit the outer loop
                        break
                    end
                end
                row_count = row_count+sum(next_to_add);
            end
        end
        % get the list of new users we just added, and concat to the users
        % left in the original list:
        users_list = [unique(newT.memberId(last_user_row:row_count-1),'stable');
            unique(T.memberId(~added),'stable')];
    end
end

Which gives newT:

memberId    productId    Rating
________    _________    ______
'B'         'x'          2     
'B'         'w'          4     
'B'         't'          2     
'A'         'x'          5     
'C'         'x'          5     
'C'         't'          4     
'A'         'y'          1     
'A'         'z'          2     

In this implementation, the rows are added user by user, and product by product, and if the next user/product to be added has more rows then what's available in newT, then we add as much rows as we cen, until we get to the rows_limit and then the loop quits.

So for a rows_limit = 4;, you will get newT as:

memberId    productId    Rating
________    _________    ______
'B'         'x'          2     
'B'         'w'          4     
'B'         't'          2     
'A'         'x'          5     

As long as there are connections between users, so each user's related products brings new users to the list, the loop continues with the new users in newT. However, it could be that we start from a node that not all other nodes are parts of its network. For instance, have a look a the following graph figure that illustrates the connections in the extended example I used in the code above:

users_net

Node D is not connected to all others, so unless we actively look for new unrelated users in T, we will never get to it. The implementation above does look for this kind of users.

EBH
  • 10,350
  • 3
  • 34
  • 59
  • thank you for your answer. but for row_limit=4 ,Table should has 4 rows i.e 'B' 'x' 2 should be insert to table. – Eli Oct 02 '16 at 11:25
  • one problem: This answer By creating a loop to all users , Checked and All rows respectively, inserted into the table until to limited rows. In the event that maybe we want start with user 'B' or any thing. Suppose a different user is selected to start to see what I mean. In fact the user has selected to begin Consider a variable. for example : InitialNode='A' or InitialNode = 'B' or anything . so Consider the above scenario. – Eli Oct 02 '16 at 14:33
  • Did you understand what I commented? – Eli Oct 03 '16 at 16:16
  • Yes, but it was holyday here so I didn't have time to answer it :) I will answer it soon. – EBH Oct 04 '16 at 16:10
  • Ok.Thank You so much.I'm waiting. – Eli Oct 04 '16 at 16:29
  • @Eli, somthing is not clear to me. Let's say that I added user 'A', then it's related products brought users 'B' and 'C' to the list. Noe I move on to user 'B', and it's related products brought user 'D' to the list. How should I continue? with user 'C' from the previous set of related products, or with user 'D' from the last set of related products? – EBH Oct 04 '16 at 21:13
  • @Eli, have a look at my edit, and see if it fits your need. – EBH Oct 04 '16 at 22:37
  • yes. this is Ok. but for row_limit = 8 last row for me is: 'C' 'z' 2 but for you is : 'A' 'z' 2 and this answer (your answer) is true. And it's true that there may not be a relationship between some nodes – Eli Oct 05 '16 at 13:10
  • @Eli, you right, I updated the answer with a small correction. – EBH Oct 05 '16 at 14:07
  • hi. I have another question in this link: [link](http://stackoverflow.com/questions/40860990/how-to-set-a-name-for-the-cell?noredirect=1#comment68937770_40860990). can you view this link? – Eli Nov 29 '16 at 08:38
  • 1
    Hi. I solve problem in above link. can you view this link: http://stackoverflow.com/questions/40996390/create-a-xls-ro-csv-file-with-certain-header-of-rows-and-columns/41022533#41022533 – Eli Dec 07 '16 at 16:30