How to store multiple output tables in a cell array

Hi everyone:
I have some output data stored in tabular format in .txt/csv files (file name format, IEA-15-240-RWT-UMaineSemi100m45mpsSNS 'file number'-'bachnumber'.out). The tables are stored in batches from 0:30:330 (30 increments). Each batch cotains 6 tables. Hence 0 contains six tables/files, numbered 1:6. I am able to store the data/file for one batch in a cell array like this:
for ii=1:6
OutputData{ii,1} = readtable(['IEA-15-240-RWT-UMaineSemi100m45mpsSNS',num2str(ii),'-0.out'],'FileType',"text",'HeaderLines',8,"ReadVariableNames",0);
OutputData{ii,1} = table2array(OutputData{ii,1});
end
However this is just for the 0 batch. I would like to formualte the code such that the tables from all batches are stored in a cell array or other appropriate storage method. I tried the following:
for ii=1:2
for jj=0:30
OutputData{jj}{ii,1} = readtable(['IEA-15-240-RWT-UMaineSemi100m43mpsJCS',num2str(ii),'-',num2str(jj)','.out'],'FileType',"text",'HeaderLines',8,"ReadVariableNames",0);
OutputData{jj}{ii,1} = table2array(OutputData{jj}{ii,1});
end
end
But rceived the folowing error:
"Unable to perform assignment because brace indexing is not supported for variables of this type."
Numerous attempts to solve this problem have failed. I would be grateful if someone could give some guidance to help me to solve it.
Thank you.
Regards,
AOAW

1 Comment

Did you clear OutputData? Before the loop it exists but it is not a cell.
Note that you cannot index at j=0

Sign in to comment.

 Accepted Answer

With MATLAB it is easier and more versatile to loop over indices, rather than looping over data. This makes it easy to preallocate the cell array used to store the imported data, which will resolve the error you describe. For example:
V1 = 0:30:330;
V2 = 1:6;
N1 = numel(V1);
N2 = numel(V2);
C = cell(N1,N2); % preallocate!!!!!
for k1 = 1:N1
for k2 = 1:N2
F = sprintf('IEA-15-240-RWT-UMaineSemi100m43mpsJCS%d-%d.out', V1(k1), V2(k2));
T = readtable(F,'FileType',"text",'HeaderLines',8,"ReadVariableNames",0);
C{k1,k2} = table2array(T); % why not just use READMATRIX ?
end
end
Store your data and code separately and use an absolute/relative path to access the data files, for example:
P = 'absolute or relative path to where the files are saved';
for ..
.. readtable(fullfile(P,F), ..)
end

16 Comments

readtable instead of readmatrix could be:
  • for matlab versions before readmatrix
  • for cases where the table contains a mix of data types but the default conversions are good enough to be able to get something useful. For example a mix of numeric and categorical could potentially be converted into an array but would not work with readmatrix.
If neither of these apply then readmatrix would be recommended.
Either way it should be documented as to why the code is written the way it is, including documentation as to why the table is not read into a temporary variable instead of directly into the cell.
T = table(categorical([1;3;1;0]),[99;64;23;12])
T = 4×2 table
Var1 Var2 ____ ____ 1 99 3 64 1 23 0 12
A = table2array(T)
Error using table2array
Unable to concatenate the specified table variables.

Caused by:
Error using categorical/horzcat
Unable to concatenate a double array and a categorical array.
Andre White's incorrectly posted "Answer" moved here:
Hi @Stephen23 I want to extract the maximum value of a variable from each of the six files in each batch (0:30:330). That is, there would be 6 maximum values for batch 0, batch 30, and so on. Then I would like to find the max of the 6 maximums (hope this is clear). I tried the first step (getting maximum value from each of the 6 files per batch) by inserting the following line in the code.
maxTwrbaseShAll{k1,k2}=max(abs(C{k1,k2}(:,TwrBsFxt)));% extracts 6 maximum value of TwrBsFxt from each table
maxTwrbaseSh_(k1,k2)=max(cell2mat(maxTwrbaseShAll_{k1,k2}));% find max of 6 maximum values
However I got the following error.
"Index in position 2 exceeds array bounds." Not sure why this happens as I thought it followed logically from your code. Please help me to solve this issue as well.
Thank you.
AOAW
@Andre White: perhaps something like this:
..
M = nan(N1,N2);
for k1 = 1:N1
for k2 = 1:N2
..
A = table2array(T);
M(k1,k2) = max(abs(A(:,TwrBsFxt))); % assuming index returns a column
C{k1,k2} = A;
end
end
After the loops you can continue with "find the max of the 6 maximums (hope this is clear)".... for me the descripton is a bit unclear, however one of these might do what you want:
V = max(M,[],1)
V = max(M,[],2)
@Stephen23 sorry that I was not clear. I essentially wanted to extract the maximum value from a particular column in each table.
I am getting the foowing error for M(k1,k2):
"Index in position 2 exceeds array bounds (must not exceed 7)."
AOAW
@Andre White: please show the exact code you are trying to run.
@Stephen23 sorry about that. Please see below.
V1 = 0:30:30;
V2 = 1:5;
N1 = numel(V1);
N2 = numel(V2);
C = cell(N1,N2); % preallocate!!!!!
M=nan(N1,N2);
for k1 = 1:N1
for k2 = 1:N2
F = sprintf('IEA-15-240-RWT-UMaineSemi100m43mpsJCS%d-%d.out', V2(k2), V1(k1));
T = readtable(F,'FileType',"text",'HeaderLines',8,"ReadVariableNames",0);
C{k1,k2} = table2array(T); % why not just use READMATRIX ?
A=C;
M(k1,k2) = max(abs(A(:,TwrBsFxt)));
end
end
AOAW
@Andre White: you will either need to extract A out of the cell array, i.e. replace
A=C;
with
A = C{k1,k2};
or use the code that I showed you. It certainly will not work if you define A to be the entirety of C.
@Stephen23 thank you. See the code below that I used initially. It did not work so that is why I changed it to A=C.
V1 = 0:30:30;
V2 = 1:5;
N1 = numel(V1);
N2 = numel(V2);
C = cell(N1,N2); % preallocate!!!!!
M=nan(N1,N2);
for k1 = 1:N1
for k2 = 1:N2
F = sprintf('IEA-15-240-RWT-UMaineSemi100m43mpsJCS%d-%d.out', V2(k2), V1(k1));
T = readtable(F,'FileType',"text",'HeaderLines',8,"ReadVariableNames",0);
C{k1,k2} = table2array(T); % why not just use READMATRIX ?
A=C{k1,k2};
M(k1,k2) = max(abs(A(:,TwrBsFxt)));
end
end
This code above also gave an error as follows:
Index in position 2 exceeds array bounds (must not exceed 7).
AOAW
@Andre White: please show the complete error message. This means all of the red text.
It is curious, that the error states "must not exceed 7", when k2 increments only up to 5: you should investigate that (e.g. print the loop iterators, DBSTOP, etc). Why is the array dim2==7 when N2==5 ? How are you iterating k2 to more than N2 ?
Why is the code indented? Is this used within a nested function or similar?
@Stephen23 you are correct. One line was missing from error. Same as previous. See below.
Index in position 2 exceeds array bounds (must not exceed 7).
I will continue with the code util I sort t out.
Thank you.
AOAW
@Stephen23 I am also looking at your other queries. I am not sure yet why dim2==7 while N2==5.
I think code is indented because I have nested for loop i.e. two for loops.
AOA
"I think code is indented because I have nested for loop i.e. two for loops."
All of the code is indented, not just the loops. Curious.
@Stephen23 I do believe the code is indented. That is how it comes up when I click on the insert matlab code in this text box.
I have solved the problem using the code below:
for ii=1:6
for jj=1:12
maxTwrBsFxtall_S(ii,jj)=max(abs(C{ii,jj}(:,TwrBsFxt)));
maxTwrBsFxt_S=max(maxTwrBsFxtall_S);
meanTwrBsFxt_S=mean(maxTwrBsFxtall_S);
stdTwrBsFxt_S=std(maxTwrBsFxtall_S);
end
It uses C{x1,x2} and finds max value and other characteristics of variables that I need.
Thanks for your help.
AOAW
@Stephen23 the first line should read "I do not".

Sign in to comment.

More Answers (1)

I suggest you simply things by creating intermediate variables. Trying to index a 2-D cell array inside a cell of another, outer 2-D cell array like
OutputData{jj}{ii,1}
is just getting way too complicated for me to understand. Try something simpler like perhaps this:
fCounter = 1;
for f = 0 : 30 : 330 % Loop over files.
for b = 1 : 6 % Loop over 6 batches.
thisFileName = sprintf('IEA-15-240-RWT-UMaineSemi100m43mpsJCS%d-%d.out', f, b);
if ~isfile(thisFileName)
% Skip it if the file does not exist.
fprintf('File does not exist: "%s".\n', thisFileName);
continue;
end
thisTable = readtable(thisFileName,'FileType',"text",'HeaderLines',8,"ReadVariableNames",0);
OutputData{b, fCounter} = table2array(thisTable);
end
fCounter = fCounter + 1;
end

3 Comments

@Image Analyst thank you. However, I received the same error when I run the script. I commented out the OuputData{b,fCounter} to see how the files were stored in thisFile and I only see one file stored. I am not sure if you can cause files to be stored as an array before readtable is executed. I have tried without success so far.
Thank you.
AOAW
OK. You accepted an answer already so I guess you got it all figured out so I won't put any more effort towards this.

Sign in to comment.

Categories

Tags

Community Treasure Hunt

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

Start Hunting!