MATLAB: Are table operations consistent with the syntax followed in matrix operations? How can we have mixed data in tables in MATLAB

MATLAB

Are table operations consistent with the syntax and behaviour seen in matrix operations?
For example, with a matrix, I can do something like this:
>> MyMat = [1,2;3,4];
MyMat(3,1) = 5
MyMat =
1 2
3 4
5 0
As you can see, it automatically generates 0 in the 3rd column of the 2nd row. Do tables follow the same consistent syntax and behaviour?
Secondly, how can I introduced mixed data such as a string in a numeric column?
MyTable(5,1) = “asdf” % Is this possible?
How would I introduce different type of structs with varying properties in the same column in tables?

Best Answer

Let us look at these questions in detail, with the help of the following code snippets:
First, let us look at the approach to add new data and delete rows in tables, and compare the consistency of this syntax and behaviour with matrices.
% initial setup
>> MyMat = [1,2;3,4];
MyMat(3,1) = 5
MyMat =
1 2
3 4
5 0
% Now, converting to a table:
MyTable = array2table(MyMat)
% Deleting the 2nd row
MyTable(2,:) = []
% Adding a new row at index 3
MyTable(3,:) = array2table([4,5])
% Alternate syntax for the same:
>> MyTable(4,:) = {4,5}
Here, you can see that the behaviour is consistent with matrices, and that the syntax is also similar, though we have to either use {} braces or convert the array into a table.
Let us now consider the example where you introduce text to a column that was previously of numerical type.
The first point to note, is that as a general principle, each column should be of the same data-type.
When you introduce text as "mixed" data, it would cause the entire column to change from numerical to text type.
Changing the data type of the first column from numerical to text can be done as follows:
newTextContent = {"someText",70;"someMoreText",32};
MyTable = [MyTable;newTextContent]
However, directly trying to assign text to a numerical column will result in a NaN, as expected.
This is by design choice as the idea is, assignments into an existing table should conform to the data type for each of the existing columns.
MyTable(6,:) = {"newText", "newText"} % results in a NaN for the second column
Now let us to come to the another example where we introduce a structure to the table.
structData = {struct('a',5),70;struct('a',6),32};
MyTable = [MyTable;structData]
This will result in the following error:
Could not concatenate the table variable 'MyMat1' using VERTCAT.
Caused by:
Error using vertcat
The following error occurred converting from double to struct:
Conversion to struct from double is not possible.
This because unlike numerical data to text data conversion, here, the entire column of text data simply cannot be converted into a column of struct data with specific fields.
This is the correct way to create table with a column of "struct" data type, consisting of the same fields:
C1 = [struct('a',5);struct('a',6);struct('a',7)];
C2 = [1;2;3];
tableWithStructData = table(C1, C2)
This is how you add additional rows to "tableWithStructData":
moreStructData = {struct('a',5),70;struct('a',6),32};
tableWithStructData = [tableWithStructData;moreStructData]
If there is a mismatch in the fields of the new data, that would once again lead to an error, as expected. However, if you do wish to insert "mixed" data in a single column in a table, you could do this using cell arrays, as follows:
mixedDataCellArray = {1; 'a'; struct('a',455); struct('b','asd')};
mixedDataTableUsingCellArrays = table(mixedDataCellArray)
In this case, though it appears that the different rows in the same column contain data of different types, they're actually cells of a cell array, as shown below:
mixedDataTableUsingCellArrays.mixedDataCellArray
ans =
4×1 cell array
{[ 1]}
{'a' }
{1×1 struct}
{1×1 struct}
If you wish to add additional rows to this table, with more mixed data, you could use cell-arrays to do so, as shown below:
% notice that on the right hand side, the struct is placed inside double {} parentheses. Here, the inner parentheses enclose the struct in a cell array.
mixedDataTableUsingCellArrays(5,1) = {{struct('e', true)}}
% alternate approach
newRowMixedData = {struct('a',5)};
mixedDataTableUsingCellArrays = [mixedDataTableUsingCellArrays;newRowMixedData]
Here is a link explaining the different ways of indexing into a table: https://www.mathworks.com/help/matlab/matlab_prog/access-data-in-a-table.html