How to combine arrays in a cell from 71 x 12 to 1 x 71?

1 view (last 30 days)
Dear all,
I had a cell named C which was 1 x 71 cell. I use the code below to split it into Cmo that is 71 x 12 cell array:
Cmo = cell(numel(C),12);
for i = 1:numel(C)
Cmo(i,:) = arrayfun(@(m){C{i}(month(C{i}.date) == m, :)},1:12);
end
I have done what I needed with split cell (Cmo) and I want to roll back it in 1 x 71 cell array again, and that is my problem.
Here is my code for doing that so far, But unfortunately it doesn't work and at the end, the Cnew will be a 71 x 1 cell (instead of 1 x 71 and field with blank cells).
% Cmo is 71 x 12 cell, and Cnew is output (1 x 71) cell
Num = ceil(length(Cmo)/12)*12-length(Cmo);
Cnew = [Cnew,cell(1,Num)]
Cnew = cell(1,72);
Cnew = reshape(Cnew,12,length(Cnew)/12);
Cnew = reshape(Cnew,size(Cnew,2)*12,1);
I don't know what to do, so if anyone knows what should I do I would be so grateful. I attached both C (the first version of Cmo) and Cmo.
Thank you all for all your helps answers and comments.
Best Regards
  2 Comments
Adam Danz
Adam Danz on 28 Jan 2020
Edited: Adam Danz on 28 Jan 2020
Some feedback on your attempt.
Num = ceil(length(Cmo)/12)*12-length(Cmo);
Cnew = [Cnew,cell(1,Num)]
% I'm not sure what's going on with these two lines but
% it doesn't matter because the next line overwrites
% Cnew.
Cnew = cell(1,72);
% Avoid "hard-coding" variables. What if your data
% changes and no longer has 72 tables? It's better
% to base that value off of something such as
% the number of rows in Cmo: size(Cmo,1)
Cnew = reshape(Cnew,12,length(Cnew)/12);
% 1) avoid using length(). Instead, use size() or numel().
% The length() function returns whichever dimension is
% longest so if Cnew only had 10 rows and 12 columns, it
% would retrun 12 but if it had 15 rows and 12 columns,
% it would return 15. So you never know what it's doing.
% 2) This just reshapes the vector into a matrix. Your
% data are much different. You've got a vector of tables
% but the matrix has 12x the elements because it breaks
% each table into 12 months of tables.

Sign in to comment.

Accepted Answer

Adam Danz
Adam Danz on 28 Jan 2020
% Loop through the rows of Cmo and combine them
% back into 1 table. Then sort the rows so that
% they are in chronological order ("date" column).
Cnew = cell(1,size(Cmo,1));
for i = 1:size(Cmo,1)
Cnew{i} = sortrows(vertcat(Cmo{i,:}),'date');
end
  1 Comment
Adam Danz
Adam Danz on 28 Jan 2020
Edited: Adam Danz on 28 Jan 2020
Just FYI, I was curious if the tables in Cnew were exactly the same as the tables in C so I exectued the following code that compares the tables between the two cell arrays and throws a warning if there is a mismatch. There were no warnings so you can be sure that the tables in Cnew match the tables in C.
Notes, isequal will be false if there is any missing data in the inputs so first I had to get rid of the missing data in both tables.
isequal(Cnew, C)
for j = 1:numel(Cnew)
C1 = reshape(table2cell(C{j}),[],1);
C2 = reshape(table2cell(Cnew{j}),[],1);
C1(cellfun(@(x)any(ismissing(x)),C1)) = [];
C2(cellfun(@(x)any(ismissing(x)),C2)) = [];
if ~isequal(C1,C2)
warning('Table %d is not equal.')
end
end

Sign in to comment.

More Answers (0)

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!