Add row and column headers to 3d matrix

Hi
I'm trying to find a simple solution to add column and row headers. So I have:
Z(164,167,59) -3d matrix
names(1x164)-row header
names2(1x167) -column header
I tested to see if i can do a 2d and was going to add a loop using a horzcat as such:
ZHDR=[names2;Z(:,:,1)]
Thank you for any help.
Kevin

9 Comments

Adam Danz
Adam Danz on 13 Dec 2018
Edited: Adam Danz on 13 Dec 2018
A matrix contains numerical data but headers usually contain strings. Are your headers numerical too? Or is all of this stored in a cell array rather than a matrix?
If you original data have a size of 164 x 167 x 59, do you expect your header-added data to have the size 165 x 168 x 59?
Kevin Teh
Kevin Teh on 13 Dec 2018
Edited: Kevin Teh on 13 Dec 2018
Sorry strings. Well i have a column and a row header. So you're right 165 x 168 x 59. Thank you.
The question is still not clear. Where do you want the header strings to appear? You cannot concatenate strings or char vectors with numerical data, except if the array is stored as a cell. So please explain exactly, what your inputs are and what you want to achieve.
Sorry it will appear before first data row and column. Top most or left most. Will look into cells. Cheers.
Stephen23
Stephen23 on 13 Dec 2018
Edited: Stephen23 on 13 Dec 2018
@Kevin Teh: what is the goal of this? Converting a perfectly good numeric array to a cell array of scalars is very unlikely to make your code better. A table is likely a better idea. Or just leave the numeric data in a numeric array.
I did not meant, if the header appear on the top and on the left, but if you want to write them in a file (text, XLS, CSV?), in the command window, if they should appear in a uitable or whatever.
+1 Stephen.
Kevin, you can create the row and column headers and store them independently from your numeric data. Converting to a cell array will slow down your code and you'll have to +1 for each row and column index to account for the headers. Many functions will require you to convert back to matrix format, too. Avoid this method if you can.
Hi
The goal was to get something like this is my other question:
I'm trying to create an index as such.
Kevin
Stephen23
Stephen23 on 13 Dec 2018
Edited: Stephen23 on 13 Dec 2018
"I'm trying to create an index as such"
All numeric arrays already have perfectly usfeul, simple, extremely efficient indices.
You explanation does not make it clear why you need to reinvent the wheel using something complex like you are trying to do, when there already exists something simpler and much more efficient (standard MATLAB indexing).
As Adam Danz already wrote, just keep your header, row, and numeric arrays separate, it will be much more efficient to work with. Or use a table. Or tell us what you are actually trying to achieve:

Sign in to comment.

 Accepted Answer

Adam Danz
Adam Danz on 13 Dec 2018
Edited: Adam Danz on 13 Dec 2018
This example creates row and column headers and puts your data and the headers into a cell array.
% Create fake data
Z = rand(164, 167, 59);
% Generate headers
rowhead = strsplit(sprintf('row%d ', 1:size(Z,1)))'; %Column vector (ie, {'row1', 'row2', 'row3', ...})
rowhead(end) = [];
colhead = strsplit(sprintf('col%d ', 1:size(Z,2))); %Row vector (ie, {'col1', 'col2', 'col3', ...})
colhead(end) = [];
% Put matrix in a cell array, add headers. The upper left corner (Zc(1,1) will be empty)
Zc = cell(size(Z) + [1 1 0]); %Create emtpy cell
Zc(2:end, 1, :) = repmat(rowhead, 1, size(Z,3)); %Place row headers in left "wall" of the 3D array.
Zc(1, 2:end, :) = repmat(colhead, size(Z,3), 1)'; %Place col headers in upper "ceiling" of 3D array.
Zc(2:end, 2:end, :) = num2cell(Z); %Fill the cell array with your data (time killer!)
% Test it
Zc(1,5) %this should be col 4
Zc(21,1) % this should be row 20

3 Comments

+1: this does what the OP wants, although I agree with the comments, that this is an inefficient method. You can simplyfy the creation of the cell strings:
rowhead = sprintfc('row%d', 1:size(Z, 1))'
or with the documented function as strings:
rowhead = compose('row%d', (1:size(Z,1)).')
Thanks, Jan. I didn't know about the undocumented sprintfc() function.

Sign in to comment.

More Answers (1)

Hi Kevin;
You may try this:
Z = zeros(165,168,59);
rowheader = cellstr('rowheader');
columnHeader = cellstr('columnHeader');
Z = num2cell(Z);
Z(2:end,1,:) = rowheader;
Z(1,2:end,:) = columnHeader;

Tags

Asked:

on 13 Dec 2018

Commented:

on 14 Dec 2018

Community Treasure Hunt

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

Start Hunting!