How do I combine rows of a 2D cell array with 1D cell arrays of varying lengths?

6 views (last 30 days)
Ulf Molich
Ulf Molich on 9 Mar 2022
Commented: Ulf Molich on 10 Mar 2022
I have a cell array of mixed datatypes, basically a table where I wanted the features of cell arrays
data(1,:) = {'sid001' 'status1' datetime(2020,1,1) datetime(2021,1,1)};
data(2,:) = {'sid002' 'status1' datetime(2020,1,1) datetime(2021,1,1)};
data(3,:) = {'sid003' 'status2' datetime(2020,1,1) datetime(2021,1,1)};
Now, I wish to append varying lengths of cell arrays to each row:
tempdata = {[1] [0] [1]}
data(1,:) = [data(1,:) tempdata]
% ...
tempdata = {[0] [0] [1] [1] [1]}
data(2,:) = [data(2,:) tempdata]
% ...
tempdata = {[1] [0] [0] [0]}
data(3,:) = [data(3,:) tempdata]
But this fails, since the size of the left side is smaller than that of the right side. What does work is this:
[n,m] = size(data);
ctemp = cell(n,5); % 5 is maximum number of columns added
data = [data ctemp];
tempdata = {[1] [0] [1]};
mtemp = length(tempdata);
data(1,m+1:m+mtemp) = tempdata;
tempdata = {[0] [0] [1] [1] [1]};
mtemp = length(tempdata);
data(2,m+1:m+mtemp) = tempdata;
tempdata = {[1] [0] [0] [0]};
mtemp = length(tempdata);
data(3,m+1:m+mtemp) = tempdata;
However, this seems like too much of a workaround, albeit I admit the idea is dirty in the first place.

Accepted Answer

Peter Perkins
Peter Perkins on 9 Mar 2022
Mixed data are what tables (or timetables) are for:
>> SID = ["sid001";"sid002";"sid003";"sid004";"sid005"];
>> Status = categorical(["Status1";"Status1";"Status2";"Status1";"Status2"]);
>> Date1 = datetime(2020,1,1:5)';
>> Date2 = datetime(2020,1,6:10)';
>> t = table(SID,Status,Date1,Date2)
t =
5×4 table
SID Status Date1 Date2
________ _______ ___________ ___________
"sid001" Status1 01-Jan-2020 06-Jan-2020
"sid002" Status1 02-Jan-2020 07-Jan-2020
"sid003" Status2 03-Jan-2020 08-Jan-2020
"sid004" Status1 04-Jan-2020 09-Jan-2020
"sid005" Status2 05-Jan-2020 10-Jan-2020
A table is perfectly happy to contain a cell array, which is good because if your numeric vectors have different lengths, that's what you need:
>> t.Vectors = {[1 0 1]; [0 0 1 1 1]; [1 0 0 0]; [0]; []}
t =
5×5 table
SID Status Date1 Date2 Vectors
________ _______ ___________ ___________ _____________
"sid001" Status1 01-Jan-2020 06-Jan-2020 {[ 1 0 1]}
"sid002" Status1 02-Jan-2020 07-Jan-2020 {[0 0 1 1 1]}
"sid003" Status2 03-Jan-2020 08-Jan-2020 {[ 1 0 0 0]}
"sid004" Status1 04-Jan-2020 09-Jan-2020 {[ 0]}
"sid005" Status2 05-Jan-2020 10-Jan-2020 {0×0 double }
Note that you do NOT want t.Vectors to be a cell array of cell arrays.
Now you can do this:
>> t.Vectors{2}
ans =
0 0 1 1 1
>> t.Vectors{2}(3)
ans =
1
  3 Comments
Ulf Molich
Ulf Molich on 10 Mar 2022
Alright, thank you very much. You have given me the courage to use tables. They seem pretty neat!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!