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

5 Ansichten (letzte 30 Tage)
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

Akzeptierte Antwort

Guillaume
Guillaume am 20 Dez. 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)
  5 Kommentare
Guillaume
Guillaume am 20 Dez. 2018
Isn't it obvious? A lot of your steps are not integer. Perhaps, you should round the values:
list.Steps = round(list.Steps);
Sunny
Sunny am 20 Dez. 2018
ohh yes, I missed this. Thanks

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Bob Thompson
Bob Thompson am 20 Dez. 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,:)
[Grades(i).data] = zeros(102,sum(block(:,5)));
col = 1;
for j = 1:size(block,1);
[Grades(i).data(block(j,3),col:col+block(j,5)-1)] = block(j,4);
col = col+block(j,5);
end
end
  1 Kommentar
Sunny
Sunny am 20 Dez. 2018
Bearbeitet: Sunny am 20 Dez. 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,:);
[Grades(i).data] = zeros(102,sum(block(:,5)));
col = 1;
for j = 1:size(block,1)
[Grades(i).data(block(j,3),col:col+block(j,5)-1)] = block(j,4);
col = col+block(j,5);
end
end

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Creating and Concatenating Matrices finden Sie in Help Center und File Exchange

Produkte


Version

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by