Error using readmatrix - Unable to determine range. Range must be a named range in the sheet or a single cell within 'XFD1048576'.
Show older comments
I am using the Name-Value pair "Range" with the readmatrix function to extract a specific range of rows from a text file, and then create a new matrix with these rows. This works well until the range of interest reaches a certain value that I think is somewhere around 1100e3.
In the example code below, if you use the first range set (First = 1000e3 and Last = 1005e3), the code works as expected. If you use the second range set (First = 1000e3 and Last = 1200e3), then I get the error mentioned in the title. Both ranges fall within the range of the original matrix X, so I don't know why this works for some values but not others. Any ideas on hot to fix this? Thanks!
X = rand(1300000,2);
writematrix(X, 'MyFile.txt');
%%% This range works
% First = 1000e3;
% Last = 1005e3;
%%% This range does not work
First = 1000e3;
Last = 1200e3;
C = readmatrix('MyFile.txt','Range',strcat(num2str(First), ':' , num2str(Last)));
Accepted Answer
More Answers (2)
"Worksheet and workbook specifications and limits
Feature Maximum limit
Open workbooks Limited by available memory and system resources
Total number of rows and
columns on a worksheet 1,048,576 rows by 16,384 columns..."
>> MaxRows=1048576;
>> First = 1000e3;
>> Last = 1200e3;
>> [First Last]<=MaxRows
ans =
1×2 logical array
1 0
>>
>> Last=1005E3;
>> [First Last]<=MaxRows
ans =
1×2 logical array
1 1
>>
Seems reasonable result to me given Excel limitations...
5 Comments
The problem/limitation is in Excel, NOT MATLAB. The maximum number of rows in a spreadsheet is the problem.
Hmmm....well, looking at the documetation it says the range named parameter is supposed to be usable for both--I had presumed that would only apply for a spreadsheet.
That appears to then turn it into implementation bug in readmatrix or the documentation is wrong in treating both Text and Spreadsheet files alike using row numbers--but would appear to be bad logic internally in the function in applying the limit algorithm to a text file as well as spreadsheet file.
To use readmatrix, you can first try the workaround to see if you force text mode that it might work by
rnge=sprintf('%d:%d',First,Last);
C=readmatrix('MyFile.txt','Range',rnge,'FileType','text'); % try force to ignore Excel limits
If that still fails, submit a bug report and use textscan with the 'headerlines' and repeat count option.
Or, just read the full array into memory if it will fit and discard the unwanted rows.
dpb
on 4 May 2020
BTW, I overlooked it earlier but the error message makes the diagnosis clear about the limit -- it has the magic number buried in it:
Range must be a named range in the sheet or a single cell within 'XFD1048576'.
although it is somewhat misleading about being a range or single cell, the upper limit is there. A message saying exceeded that value would be more informative and accurate it appears.
Guillaume
on 4 May 2020
To answer a few of the questions raised here, I went through the code of readmatrix. In R2020a, the range validation is specific to each filetype (whether supplied or not). Text files range validation and excel files range validation are completely different code paths. That's the good news.
Bad news, is that indeed the text range validation indeed limits the range to XFD1048576, which doesn't make much sense. There is unfortunately no way to bypass this check.
I suggest raising a service request asking for that artificial limit to be removed. I suspect it's a legacy limit from early implementations of detectImportOptions.
dpb
on 4 May 2020
" I went through the code of readmatrix..."
If you can fight your way thru that maze after the initial dispatch line, power to you...I'm too much an old fogey to be able to even figure out where the pieces are buried, what more read it. I wish TMW had stayed w/ mostly procedural code; the complexities are just more than justified seems to me...
dpb
on 4 May 2020
Given that it appears readmatrix is fatally flawed for you use case, try something like
First = 1000e3;
Last = 1200e3;
L=First-Last+1; % number records to read
buf=cell(L,1); % allocate a cell to hold the input lines
fid=fopen('yourfile.txt');
for i=1:First-1 % get past unwanted records at beginning...
fgetl(fid);
end
for i=1:L % read L wanted records
buf(i)={fgetl(fid)}; % put in cellstr buffer
end
fid=fclose(fid);
You can then pass the buffer to textscan w/ cellfun to convert to char data.
Alternatively, use textscan directly
fmt='fmtstringtomatchinputrecord';
fid=fopen('yourfile.txt');
data=cell2mat(textscan(fid,fmt,L,'collectoutput',1));
fid=fclose(fid);
Categories
Find more on Spreadsheets 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!