MATLAB: Populating a cell using a loop

data filesdirloop

This is my code
a = dir;
i=3;
n=1;
b = zeros(n,55);
while i<=43
d = a(i).name;
A = textscan(fopen(d),'%f %f %f %f %f %f %f %f %f %f %f %f %f %f %s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %s %s %f %f %f %f %f %f %f %f', 'Delimiter',',','Headerlines',1);
A_time = A{1,1};
B_time = num2str(A_time);
x = datenum(B_time,'yyyymmddHHMM');
b = A(n,:);
i=i+1;
n=n+1;
end
I've for help with this code in a couple different ways and while I appreciate any help, a lot of it has not been what I'm looking for. I'm trying to run this but when I do, it says that the index exceeds matrix dimensions for the line b=A(n,:). Please just help me figure out why this isn't working. I know it's difficult without the data files but just know that they all have 55 columns. When the part in the loop is run by itself up to b, A is a 1×55 cell. I want b to be a cell with 55 columns but with n rows. one row for each data file that I run. Please just tell me what is wrong with this code. Let me know if clarification is needed

Best Answer

textscan returns a 1x55 cell array, where the format string specifies the 55. So your code:
A = textscan(fopen(d),'%f %f %f %f %f %f %f %f %f %f %f %f %f %f %s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %s %s %f %f %f %f %f %f %f %f', 'Delimiter',',','Headerlines',1);
will result in a 1x55 cell array. Then a few lines later you write this:
b = A(n,:);
because A only has one row, as soon as n>1 this will be an error, because C only has one row, and so requesting anything from its (non-existent) second (or higher) row will be an error.
"I want b to be a cell with 55 columns but with n rows. one row for each data file that I run"
I really really really recommend that you don't do that: that would require putting scalar numeric data into the cells of a cell array, which just makes it much harder to work with numeric data. You should really keep the numeric data in numeric arrays, or use a table. Because you have a few columns which are character, this complicates the importing a little bit, but there are reasonable solutions which you should look at:
  • If you do not need those character columns then get textscan to ignore them with %*s in the format string. Then could trivially get textscan to collect all of the numeric data into one numeric array, using the CollectOutput option. Very simple, but you would lose some data.
  • Use the CollectOutput option to collect the data into arrays of matching types: this would give you one 1x5 cell array C, containing an Nx14 numeric array, an Nx2 char cell array, an Nx29 numeric array, an Nx2 char cell array, and an Nx8 numeric array (or whatever sizes that format string gives you). I recommend this option.
  • Use a table. These are a very convenient way for handling mixed data (e.g, numeric, char, categorical) and analyzing it. It has many powerful methods and operators for processing data by groups, and for statistical analyses.
Or your proposal:
  • If you really want to get all of your data into one cell array (which will make any numeric processing slow, inefficient and complex), then you will need to post-process the data after it has been imported, something like this: detect numeric columns, convert numeric columns to cell array containing numeric scalars (e.g. num2cell), then concatenate all into one cell array. I strongly advise you to avoid doing this.