# Create a zero matrix and update cells based on other column values

8 views (last 30 days)
Sunny on 20 Dec 2018
Commented: Sunny on 20 Dec 2018
Hi,
I have a matlab table (attached in this thread) named 'List' (matlab table format) with 5 columns as shown below. I am looking to create a zero matrix for each unique subject value in a struct, Every matrix has fixed rows 102, but column size depends on the sum of values in 'Steps' column for that subject. For example, for subject 9 the zero matrix is 102x45. Here 45 is based on sum of 15+20+10 in Steps column, and for subject 10 the matrix is 102x13 where 13 columns are from sum of 5 + 8. Once these matrices are created, I am trying to pick the value from ANS column on each row and place it in the zero matrix related to subject. For example, when we scan first row which is subject 9, the value in ANS is -1, this is placed in Zero matrix relevant to subject 9 at row 10 (based on 'ID' column in the table) and in the 15 columns (-1 will be in 10x1,10x2,..10x15) this is based on the value in Steps column. The next row it starts at row 8 and coulmn 16 as we used till column 15 earlier and this continues till 20 values of 1 are place in (8x16....8x15) and this repeats till all data related to subject 9 is populated. This loops for all the subjects.
List : Format type Table
Subject Number ID ANS Steps
9 1 10 -1 15
9 2 8 1 20
9 3 10 -1 10
10 1 5 1 5
10 2 6 -1 8

Guillaume on 20 Dec 2018
I would do it like this:
First create a function to create a matrix, given column vectors of ids, ans, and steps for a single subject (I'm using more meaningful variable names. You certainly shouldn't call a variable ans):
%saved in its own m file:
function m = makeMatrix(rows, values, ncols)
m = zeros(102, sum(ncols)); %create matrix full of zeros
m(sub2ind(size(m), repelem(rows, ncols), (1:sum(ncols))')) = repelem(values, ncols);
end
It is then easy to apply that to any table using rowfun:
%demo table:
t = array2table([9 1 10 -1 15
9 2 8 1 20
9 3 10 -1 10
10 1 5 1 5
10 2 6 -1 8], ...
'VariableNames', {'Subject', 'Number', 'ID', 'ANS', 'Steps'});
%apply function
c = rowfun(@makeMatrix, t, 'GroupingVariables', 'Subject', 'InputVariables', {'ID', 'ANS', 'Steps'}, 'OutputFormat', 'cell');
You can then transforim that output cell array into a structure:
s = cell2struct(c, compose('Subject%d', unique(t.Subject)), 1)
Sunny on 20 Dec 2018
ohh yes, I missed this. Thanks

Bob Thompson on 20 Dec 2018
I'm going to take a stab at what you're looking for here, let me know if I need to adjust something.
I'm going to begin with the assumption that you can get your data into an array (without labels) with the arrangement shown above.
for i = unique(List(:,1));
block = List(List(:,1)==i,:)
col = 1;
for j = 1:size(block,1);
col = col+block(j,5);
end
end
Sunny on 20 Dec 2018
Edited: Sunny on 20 Dec 2018
Will try this. Can you check and inform what I am doing wrong in this? Error, Matrix dimensions must agree
Subject = [9;9;9;10;10];
Number = [1;2;3;1;2];
ID = [10;10;10;5;6];
ANS = [-1;1;-1;1;-1];
Steps = [15;20;10;5;8];
List = table(Subject,Number,ID,ANS,Steps);
List = table2array(List)
for i = unique(List(:,1))
block = List(List(:,1)==i,:);
col = 1;
for j = 1:size(block,1)
col = col+block(j,5);
end
end

### Categories

Find more on Tables in Help Center and File Exchange

R2018a

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!