3
\$\begingroup\$

I have an array matrix, for example A(3,3), I want to make a table with header names like, ['force','mass','acceleration'], the second row contains the units (subheader), ['N','Kg','m/s^2'], and the rest of the table contains the elements of A.

I want to export this table as a (.dat) file, how can I do that in an efficient way (I want to implement it for a large number of matrices)?

This is my code, which I believe it is not professional.

A = [1,2,3;4,5,6];

C(1,:) = {'force','mass','acceleration'};
C(2,:) = {'N','Kg','m/s^2'};

C(3,:) = num2cell(A(1,:));
C(4,:) = num2cell(A(2,:));
T = cell2table(C)

writetable(T,'tabledata.dat')

also this is a new update

A = [1,2,3;4,5,6;7,8,9];
C(1,:) = {'N','Kg','m/s^2'};
C(3:5,:) = num2cell(A(:,:));

T = cell2table(C)

T.Properties.VariableNames = {'force' 'mass' 'acceleration'};

writetable(T,'tabledata.dat','Delimiter','\t') 
\$\endgroup\$
5
\$\begingroup\$

I'm assuming the data in variable A is calculated somehow in MATLAB, and that you have a matrix A that you want on a tab-delimited format, with headers. If that's the case, then writetable is probably your best bet (as you have figured out).

The expressions below are very hard to scale, since 100 rows of data results in 100 rows of code.

C(3,:) = num2cell(A(1,:));
C(4,:) = num2cell(A(2,:));

Simply doing data_in_cells = num2cell(A) is much more robust and clean.

The following is probably the best way to achieve what you want:

A = [1,2,3;4,5,6];

headers = {'force', 'mass', 'acceleration'};
units = {{'N'},{'Kg'},{'m/s^2'}};   % or: units = num2cell(units);  

table_of_data = cell2table([units; num2cell(A)]);
table_of_data.Properties.VariableNames = headers;

writetable(table_of_data,'tabledata.dat','Delimiter','\t')

The reason why I use a double nested cell for units is that when trying to create the matrix MATLAB checks if all elements in each column are of the same type, and if so concatenates them as that type. In MATLAB, [65 66, 'C'] becomes ABC, because it converts the entire array to chars. Since the first column contains a single character N, this column looks like:

'N'
1
4

MATLAB translates this to: char([78; 1; 4]). 1 and 4 when converted to ASCII-characters becomes: "Start of heading", and "End of transmission". These are not printable ASCII. Placing N inside a cell will result in the correct result, since MATLAB can't concatenate a cell and integers.

Note that I'm not placing headers, units and the data in a single cell as you did (C). This is because:

  1. You don't need that cell anywhere
  2. Avoid the additional memory overhead
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.