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

1 visualización (últimos 30 días)
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);
fclose(fileID);
%% 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.

Respuestas (2)

dpb
dpb el 19 de Ag. de 2020
Editada: dpb el 19 de Ag. de 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
fid=fopen('fileExample.txt','r');
data=textscan(fid,fmt,'HeaderLines',1,'CollectOutput',1,'Delimiter','\t');
fid=fclose(fid);
>> 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 comentarios
Jane Fowler
Jane Fowler el 20 de Ag. de 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
dpb el 20 de Ag. de 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.

Iniciar sesión para comentar.


Walter Roberson
Walter Roberson el 20 de Ag. de 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);
fclose(fid)
Though I would suggest that readtable() is a better idea.
  5 comentarios
Walter Roberson
Walter Roberson el 20 de Ag. de 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);
fclose(fid)
ans =
0
>> 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 el 20 de Ag. de 2020
OK, well, I'm getting the error I described.

Iniciar sesión para comentar.

Categorías

Más información sobre Logical en Help Center y File Exchange.

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by