The logical indices in position 2 contain a true value outside of the array bounds.

2 views (last 30 days)
The logical indices in position 2 contain a true value outside of the array bounds.
Error in test (line 56)
OCVData.(fields{theHeader}) = [OCVData.(fields{theHeader});num(:,ind == 1)];
Code:
headers = {'A','B','C','D','E','F'}; (Headers from xls files)
fields = {'I','J','K','L','M','N'};
[num,txt,raw] = xlsread(OCVFile,sheets{theSheet}); % read data
for theHeader = 1:length(headers), % parse out data that we care
ind = strcmp(txt,headers{theHeader}); % about
fprintf('value of ind %s\n',ind); % status
OCVData.(fields{theHeader}) = [OCVData.(fields{theHeader});num(:,ind == 1)];
end
This code is to read one excel from local and stor few data on OCVdata.when ind value is 1 its copy respected column from num and store in OCVdata. one excelanyone please advice on above issue and how to solve this problem.

Accepted Answer

Walter Roberson
Walter Roberson on 2 Oct 2020
When you use xlsread(), the first variable that is returned, which you have indicated using the name num, is not generally size equivalent to the entire worksheet.
xlsread() reads the entire worksheet as a cell array of text (at least when you use .xlsx files -- they are text really.) Then it starts examine each text cell and checking to see whether it can convert the text to a number: if it can then it stores the number in the corresponding position in a numeric array; if the text cannot be converted to number, then a NaN is stored in the corresponding position in the numeric array.
After that process of converting text is done, there is a numeric array that is the same size as the original worksheet. But that full-sized array is not exactly what is returned.
Instead, MATLAB examines the numeric array, and throws away all leading or trailing rows and columns that have only NaN in them. So, for example,
name extension year
Ringo 107 2004
Belle 103 2007
Donner N/A unknown
F N/A 2009
Would get converted first to
nan nan nan %the header is not numeric at all
nan 107 2004 %the name is not numeric
nan 103 2007 %the name is not numeric
nan nan nan %none of the fields are numeric
nan nan 2009 %the name is not numeric; "N/A" is not numeric
then the nan trimming would be done. The first row is all Nan, so it is potentially to be discarded. The second row has the number 107 in it so it is not all nan, so the second row is to be kept. The third row has the 103 so it is not all nan, so the third row is to be kept. The fourth row is all nan, so it is potentially to be discarded. The fifth row has the 2009 in it so it is not all nan, so the fifth row is to be kept. Now, the first row to potentially be discarded is an "outside" row, no rows with numbers before it, so it can actually be discarded. The fourth row is potentally to be discarded, but the fifth row is after it and that one is not all nan, so the fourth row is not an outside row of all nan, and so is not to be discarded. After the row discards:
nan 107 2004 %the name is not numeric
nan 103 2007 %the name is not numeric
nan nan nan %none of the fields are numeric
nan nan 2009 %the name is not numeric; "N/A" is not numeric
Then we look at the columns. The first column is all nan, so it is potentially to be discarded. The second column has the number 107 in it, so it is not to be discarded. The third column has the number 2004 in it, so it is not potentially to be discarded. So the first column is indeed an outer column that is all nan, so the first column can be discarded, giving you
107 2004
103 2007
nan nan
nan 2009
and that is what would be returned in num in this example. Notice that it has only 2 columns and 4 rows even though the worksheet had 3 columns and 5 rows.
The second output of xlsread(), the txt output, starts with the cell of values that was read in as text, but every cell that was converted to a number for the purpose of the num output, is converted to emptiness. Using the same example, that would give you
{'name', 'extension', 'year'
'Ringo', [], []
'Belle', [], []
'Donner' 'N/A', 'unknown'
'F', 'N/A', [] }
Notice that this is three columns.
You then compare the txt to the headers one by one. The fifth row first column matches the 'F' header in the list, so ind would be
[false false false
false false false
false false false
false false false
true false false]
and ind == 1 would be exactly the same matrix (the == 1 is redundent for this purpose). You now use that 5 x 3 array as the second index into num -- num(:,ind) . But the fifth row of ind has an entry that is true, which is a problem because num only has four rows.
What should you take away from the analysis?
This: Never count on your num array being a particular size or having or not having particular rows or columns -- or at least never count on it if the spreadsheet might have been edited by a user (who might have put in text in unexpected places, or numbers for that matter -- the first row would not be discarded if one of headers had happened to look like a number.)
If you are working with anything that might have been edited by a user, and you need to match text entries and numeric entries, then you have two realistic possibilities:
  1. ignore the num output and pull the numeric values out of raw; or
  2. Stop using xlsread(). Convert to using readtable() or readcell()

More Answers (0)

Categories

Find more on Cell Arrays 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!