Most readable syntax to fill table in a for cycle
10 views (last 30 days)
Show older comments
What is the clearest syntax to fill a table entry by entry in a for cycle? For instance, take the following code that checks convergence of a certain iteration.
format short e
x = rand();
T = table();
for k = 1:5
x = 1/2 * (x + 1/x);
T.x(k) = x;
T.residual(k) = abs(x - sign(x));
end
T
This code looks very readable to me, but it has the drawback of displaying lots of spurious warnings.
All other solutions I have found require specifying things in two places; for instance, setting column types and names in advance and then identifying them by position. I find this cumbersome because I would like to be able to specify things in only one place. This code should go in my lecture notes and it is meant for readability and "least surprise", not performance.
0 Comments
Accepted Answer
Les Beckham
on 11 Apr 2023
There probably isn't a significantly cleaner way to do this. See below for a way to suppress the warnings.
format short e
x = rand();
T = table();
warning('off', 'MATLAB:table:RowsAddedExistingVars')
for k = 1:5
x = 1/2 * (x + 1/x);
T.x(k) = x;
T.residual(k) = abs(x - sign(x));
end
T
Run the line below after running your code once to find out the warning ID, then add the warning('off', ... command above using the id
% [msg, id] = lastwarn
1 Comment
Dr D
on 18 Apr 2023
Note, of course, that you've turned the warning off for the rest of the MatLab session - all code that follows this point. For robustness, MatLab makes it pretty easy to capture the current warning state, then re-set it after the loop. Like this:
oldWarn = warning( 'off', 'MATLAB:table:RowsAddedExistingVars' );
for ...
end
warning( oldWarn );
More Answers (2)
Antoni Garcia-Herreros
on 11 Apr 2023
Hello
You could create the arrays containing x and residual beforehand and create the table afterwards. Something like this:
x=zeros(5,1);
T = table();
x(1)=rand();
for i=2:5
x(i) = 1/2 * (x(i-1) + 1/x(i-1));
end
y=abs(x - sign(x));
T.x=x;
T.residual=y
0 Comments
Dr D
on 18 Apr 2023
I know you said you don't want to specify the column names & types in advance, but there's one thing to consider for the future. If the table will become very large, adding one row at a time will make the code very slow as the table grows and large blocks of memory have to be reallocated in the background. In professional programming, the acceptable solution is to preallocate your memory. For a table, the best way to do that is to specify the table format in advance, then allocate the entire block of memory one time.
For those who are not familiar, it looks something like the below. Notice how simple it is to specify and preallocate the entire table in only two lines.
(Note, you could do it in one line by specifying a row count in the 'Size' parameter. I find that different versions of MatLab don't properly fill the table with their "missing" values when you do that so since my codes have to run on many different versions, prefer the extra step of explicitly assigning missing().)
T = table( 'Size', [0 2], 'VariableNames', {'x', 'residual'}, 'VariableTypes', {'double','double'} );
T{1:5,:} = missing();
for k = 1:height(T)
...
0 Comments
See Also
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!