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

10 views (last 30 days)
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
Peter Perkins
Peter Perkins on 10 Mar 2022
Yes. As far as the Vectors variable goes, there's not a lot of difference in using t.Vectors and in using your data{:,end} (or whatever). But for the other variables in the table, your life will be easier, for example, finding all the rows for Status2.
It'sa hard to say exactly what that kine would be, because it looks like you've changed things from your OP, and that line seems to have nothing to do with your vectors.
data3(:,1),data4(i,1) probably becomes something like t3.SiD==t4.SID(i)
find(dateMat(:,1)==data4{i,5}) probably becomes something like find(t3.Date1==t4.Date1(i))
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)

Categories

Find more on Tables in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!