MATLAB Answers

"textscan" import leads to Undefined operator '.*' for input arguments of type 'cell'.

조회 수: 1(최근 30일)
Jane Fowler
Jane Fowler 19 Aug 2020
댓글: dpb 20 Aug 2020
I am using "textscan" to import data from two different files. I use the data to do a calculation:
calculationResult = (((a/((b./c)+d+e+f))+g) ./ (f_1.*f_2.*f_3))
I have no problem importing and using data for parameters a to g. Here is how Matlab's "import" facility reads in and allocates the data to variable names:
e = dataArray2{:, 2}
However, for parameters f_1, f_2, and f_3, the "import" facility does this (I attached an example of the file; the real one is much larger):
f_1 = cell2mat(rawNumericColumns(:, 4));
and I get this error:
Undefined operator '.*' for input arguments of type 'cell'.
Here is my import script:
filename = X
delimiter = '\t';
formatSpec = '%s%s%*s%*s%*s%*s%*s%[^\n\r]';
fileID = fopen(filename,'r');
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'ReturnOnError', false);
%% Convert the contents of columns containing numeric text to numbers (not included here).
rawNumericColumns = raw(:, [XXX]);
rawCellColumns = raw(:, 1);
R = cellfun(@(x) ~isnumeric(x) && ~islogical(x),rawNumericColumns); % Find non-numeric cells
rawNumericColumns(R) = {NaN}; % Replace non-numeric cells
f_1 = cell2mat(rawNumericColumns(:, 4));
From this other post:
I read this: "They define a cell, and since cells can contain anything — including character variables — arithmetic operators are not defined for them. You have to remove numeric data from cell arrays to use them in numeric calculations." However, I don't know how to do this as my cells are not defined by curly brackets.
Does anyone know how I can deal with this? Thank you.

  댓글 수: 1

KSSV 19 Aug 2020
Show us how your file is and how you have imported.

댓글을 달려면 로그인하십시오.


dpb 19 Aug 2020
편집: dpb 19 Aug 2020
Use format spec that matches the file -- unfortunately, the file was created w/o using quoted string to delimit the date/time string and the %{}D format string requires %q scanning -- but the delimiter being a tab lets you bring it in as string and convert. Use something like--
fmt=['%s' repmat('%f',1,6)]; % one datetime string, six floats per record
>> data =
1×2 cell array
{2×1 cell} {2×6 double}
>> data{:,1}
ans =
2×1 cell array
{'2015-03-06 14:00:00'}
{'2015-03-06 15:00:00'}
>> fid=fclose(fid);
>> datim=datetime(data{:,1},'inputformat','yyyy-MM-dd HH:mm:ss')
datim =
2×1 datetime array
06-Mar-2015 14:00:00
06-Mar-2015 15:00:00
>> f=data{2}
f =
1.03 1.13 1.05 1.05 1.23 -9999.00
1.03 1.12 1.05 1.05 1.23 885.31
For disparate data types, I'd suggest using readtable would be simpler as can hold the variables in the one table and avoid the creation of the cell arrays inherent with textscan
You can, if you so choose, also use the variable names altho I would recommend strongly against creating six f_sub_n variables; it makes for much more difficult code than using an array.

  댓글 수: 2

Jane Fowler
Jane Fowler 20 Aug 2020
@dpb, thank you for your help. If I understand you correctly, there's a problem with my format specifications for reading the file in. I went back and used Matlab's "import data" function in case I made a mistake. I'm still getting the same error though.
dpb 20 Aug 2020
Well, the above works -- altho I just realized belatedly my comment re: the datetime D format needing the double-quotes around the string was a faux pas on my part -- I had used "hh" instead of "HH" for the hour field in the format string was the cause of the failure on my end.
We would have to see the exact code in context with the error message to discern precisely where the issue is...the above works as will correcting the format string and using
fmt=['%{yyyy-MM-dd HH:mm:ss}D' repmat('%f',1,6)];
which will return a cell array of two arrays, the first a datetime, the second a double. As above, dereference those with the curlies "{}" to convert to arrays from cell arrays.
As Walter also says, "USE A TABLE"; they're more convenient...and detectImportOptions will figure out the file format for you in almost all cases.

댓글을 달려면 로그인하십시오.

Walter Roberson
Walter Roberson 20 Aug 2020
fmt = '%{yyyy-MM-dd HH:mm:ss}D %f%f%f%f%f%f';
fid = fopen('fileExample.txt');
data = textscan(fid, fmt, 'HeaderLines', 1','Delimiter', '\t', 'CollectOutput', true);
Though I would suggest that readtable() is a better idea.

  댓글 수: 5

표시 이전 댓글 수: 2
Jane Fowler
Jane Fowler 20 Aug 2020
I'm using 2016b. I did fill it in initially, but my title was too long and the version field had cleared when I edited the question. I didn't know how to add it subsequently. I think I'll use Python instead. This has taken over a day now and I'm no closer to a solution. Thanks.
Walter Roberson
Walter Roberson 20 Aug 2020
I just tested in R2016a, and the code I posted works fine.
>> fmt = '%{yyyy-MM-dd HH:mm:ss}D %f%f%f%f%f%f';
fid = fopen('fileExample.txt');
data = textscan(fid, fmt, 'HeaderLines', 1','Delimiter', '\t', 'CollectOutput', true);
ans =
>> data{1}
ans =
2015-03-06 14:00:00
2015-03-06 15:00:00
>> data{2}
ans =
1.0e+03 *
0.0010 0.0011 0.0010 0.0011 0.0012 -9.9990
0.0010 0.0011 0.0011 0.0011 0.0012 0.8853
Jane Fowler
Jane Fowler 20 Aug 2020
OK, well, I'm getting the error I described.

댓글을 달려면 로그인하십시오.

Community Treasure Hunt

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

Start Hunting!

Translated by