MATLAB Answers

Cell2table header transfers

72 views (last 30 days)
Richard Rees
Richard Rees on 16 Jan 2020
Commented: Guillaume on 17 Jan 2020
Good afternoon everyone,
I would like some advice, I have a table that I have converted into a cell array to do do some rearranging of the data to help in further calculations. What I would like to do is convert a copy of this cell array into a table and attach pre-existing headers back, including a new one, just to keep track of the variable names. I have tried creating tables within the cell array loops and assigning the headers to it, but it is only applied to the primary table because of the way the code works in reconfiguring the data.
What the code does is rearrange the table content into a new cell array, so that each slope angle how has a 1x3 cell (H,M,L) with the parameters (X,Y displacements etc) contained within. The two attachments are an image of the primary data table with the 1x3 cell within represent 'High, Med, Low' levels (file too big to attach). and the second is a light versions of the output data from the code, so you get an idea (First layer = Slope angles, 2 seconds layer = H,M,L and 3rd = Parameters)
Is there a way to re-arrange the table while maintaining the header names? Or my preference, attach the header names back at the end?
Many thanks
(Note: There is an empty cell for the 3rd nested cell of each)
New_cell = cell(1,5);
SA = [27,45,63,76,90]
WL = {'High','Med','Low'};
for a = 1:size(C_SMC,1)% Rows table (SA's)
Slope{a} = sprintf('Slope_%d',SA(a)); %Use the loop to create table names
for b = 2:size(C_SMC,2) %Number parameters (igornes col_1 SA)
for c = 1:size(C_SMC{a,b},1) % WL's
New_cell{a}{c}{1,b} = C_SMC{a,b}{c,1};
Pre_calc_tab = cell2table(New_cell,'VariableNames',Slope)


Guillaume on 16 Jan 2020
First reaction: why are you converting a table to a cell array just to rearrange it? You can do your edits directly with the table.
But anyway, I'm afraid I don't really understand what you're trying to do. Perhaps, you should attach an example table rather than a screenshot of it. In my opinion, a table containing cell arrays is not very useful, lots of powerful table functions don't really work anymore.
I'm not sure what you call the header. matlab tables don't have headers. They do have several properties such as VariableNames, VariableDescriptions, etc. and at any point you can easily change these to whatever you want (particularly since R2019b)
Guillaume on 17 Jan 2020
Richard Rees' comment wrongly posted as answer moved here:
Thanks to both of you replying. Attached is a slimmed down version of the table.
Reading the above, if it is inpractical to achieve what I need to do, then that is fine because the follow on code to this works. On the side, I would really appreciate the empty cell being removed formed per loop within the New_cell_trans array because it is generating zeros in a matrix later on.
%Pre TecPLOT
slice_mean = load('Table_SA_mean.mat');
SM_C = struct2cell(slice_mean);
SM_C = vertcat(SM_C{:});
headers = SM_C.Properties.VariableNames(1,2:end);
Tab = SM_C.SlopeAngles % Transpose
%% 1st reorganisation - Takes the table data and rearranges into SA and WL orinetated cells
New_cell = cell(1,5);
WL = {'High','Med','Low'};
for a = 1:size(C_SMC,1)% Rows table (SA's)
Slope{a} = sprintf('Slope_%d',Tab(a)); %Use the loop to create table names
for b = 2:size(C_SMC,2) %Number parameters (igornes col_1 SA) - PROBLEM: Generates []
for c = 1:size(C_SMC{a,b},1) % WL's
New_cell_trans{a}{c}{1,b} = C_SMC{a,b}{c,1}'; %Transpose matrix
Pre_calc_tab = cell2table(New_cell,'VariableNames',Slope);
Guillaume on 17 Jan 2020
Despite the bugs, I think I understand what you're trying to do. For a start, you're trying to transpose the table (rows2vars will do that for you), however I'm not entirely clear what you want as rows of the table. Your current code ends up with a table with only 1 row which is not very useful.
Then each variable is a 1x3 cell array (high, med, low) of 1x17 cell array (your original variables) of matrices all the same size. I don't know what you're going to do with your data but this multilevel cell array design doesn't seem very easy to use. Certainly, I don't see the point of a table for that. Since all the matrices are the same size, I'd concatenate them into a 3D or 4D matrix to get rid of the cell arrays. Or maybe use a table whose variables are themselves tables.
Can you confirm what the final table should look like? Then we can work on the code to generate it.
Unrelated to this problem, a few comments on your code:
SM_C = vertcat(SM_C{:});
would imply that you expect more than one variable in the mat file, and that all these variables are tables that can be concatenated, and that concatenating them make sense. If that's not the case, then:
SMC = SMC{1};
would be clearer, or possibly even better, replace the two lines by:
varnames = fieldnames(slice_mean);
SMC = slice_mean.(varnames{1});
I would recommend that you use 1D indexing when dealing with vectors. Your 2D indexing assumes row/column vectors and will error if the vector happens to be the other way, so:
headers = SM_C.Properties.VariableNames(2:end);
New_cell{a}{c}{b} = C_SMC{a,b}{c};
It's less to type as well!
Finally, I'd recommend better variable names, ones that have meaning. if you're iterate over the rows of a table, then row, i_rows or table_row is much clearer than a, similarly var, i_vars or table_var is much clearer than b. I kept having to go back to understand what {a, b}{c} referenced. {table_row, table_var}{level} is much easier to undersand.

Sign in to comment.

Answers (1)

Spencer Chen
Spencer Chen on 16 Jan 2020
Your Test_cell format is not compatible with the SM_C table you have in Annoation.jpg.
To add a new field to an existing table, you would need the same number of rows. So this will work, (by rotating your Test_cell into a column vector:
SM_C.newField = Test_cell';
But I'm not sure if this is what you want to achieve.
One more tip, if you store your HML values as row vectors instead of column cell arrays, you can visualize them and work with them better in a cell. Try:
>> a = table();
>> a.magic3 = magic(3)


Richard Rees
Richard Rees on 17 Jan 2020
Hello Spenser, I accidently responded to Guillaume instead of you last night. Instead of reposting the above, would you still be able to help?
Guillaume on 17 Jan 2020
No you didn't respond to me (you should have!) Instead you answered your own question. I had to repost your answer as a comment. As it wasn't entirely clear who you were addressing it and since I'm not sure Spencer answered your question, I reposted it as a comment to the question itself.

Sign in to comment.


Community Treasure Hunt

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

Start Hunting!