How to save a text file with headers?

For context, the full code reads data from a text file, calibrates and converts the data to degrees, and then saves the new data in 4 columns with 108766 rows each. This is what I am currently using to save the new text file:
function calibratedData = applyCal(fname,Ey,components,rawData,Calib)
% applies calibration (gain and shift) to raw data; function returns
% calibrated data ONLY for 'components'!
calibratedData = [];
for i = find(components)
calibratedData(:,Ey(i).datacolumn) = ( rawData(:,Ey(i).datacolumn) - Calib(1,Ey(i).datacolumn) ) * Calib(2,Ey(i).datacolumn);
end
%save as textfile:
s = strtok(fname,'.');
SaveName = [s, datestr(now, ' yyyymmddTHHMMSS'),' calibrated.txt'];
save (SaveName, 'calibratedData', '-ASCII');
end
This works - but I need there to be a header at the top of each column. The headers need to be "LE Horizontal" "LE Vertical" "RE Horizontal" and "RE Vertical". Any help would be appreciated! Thank you!

3 comentarios

Adam Danz
Adam Danz el 24 de Ag. de 2020
Editada: Adam Danz el 24 de Ag. de 2020
Convert your array to a table using array2table where you can also specify the header names. Then use writetable to write the table to a text file.
Dorsa Mir Norouzi
Dorsa Mir Norouzi el 24 de Ag. de 2020
I tried to do this, but I get an error saying that my array "calibratedData" is undefined. But it is defined... so I'm not sure what's going on.
Adam Danz
Adam Danz el 24 de Ag. de 2020
Editada: Adam Danz el 24 de Ag. de 2020
That's not a problem with any Matlab functions. That indicates that you're building the table in the wrong place, specifically, before the vcalibratedData variable is defined or, perhaps, in a different workspace.

Iniciar sesión para comentar.

 Respuesta aceptada

dpb
dpb el 24 de Ag. de 2020
function calibratedData = applyCal(fname,Ey,components,rawData,Calib)
% applies calibration (gain and shift) to raw data; function returns
% calibrated data ONLY for 'components'!
calibratedData = [];
for i = find(components)
calibratedData(:,Ey(i).datacolumn) = ( rawData(:,Ey(i).datacolumn) - Calib(1,Ey(i).datacolumn) ) * Calib(2,Ey(i).datacolumn);
end
%save as textfile:
s = strtok(fname,'.');
SaveName = [s, datestr(now, ' yyyymmddTHHMMSS'),' calibrated.txt'];
names={'"LE Horizontal"','"LE Vertical"','"RE Horizontal"','"RE Vertical"'};
writecell(names,SaveName,'delimiter','space');
save(SaveName, 'calibratedData', '-ASCII' '-append');
end
saves having to create the table just for the purpose of writing a header line. Second time come up in last couple of days...see

12 comentarios

Dorsa Mir Norouzi
Dorsa Mir Norouzi el 24 de Ag. de 2020
Thank you so much! This seems like it will work. However, I am running R2016a, and I don't think that writecell works on this version. Is ther another function I could use?
Adam Danz
Adam Danz el 24 de Ag. de 2020
Editada: Adam Danz el 24 de Ag. de 2020
Nice shortcut, dpb.
"I am running R2016a"
I just noticed that you did document your Matlab version when you wrote the question. I missed that. writecell was released in r2019a. writetable was released in 2013 so that should work in your release.
Dorsa Mir Norouzi
Dorsa Mir Norouzi el 24 de Ag. de 2020
Editada: Dorsa Mir Norouzi el 24 de Ag. de 2020
Thank you for your response. I tried writetable as well, and I got an error saying "Undefined function 'write' for input arguments of type 'cell'", and then an error in the actual writetable function on line 117 "write(a, filename,varargin{:})
Adam Danz
Adam Danz el 24 de Ag. de 2020
Editada: Adam Danz el 24 de Ag. de 2020
Are you shadowing the write function?
which('write','in','writetable')
That should return one line pointing to the built-in matlab function used by writetable. It does not look for nested functions so make sure your file doesn't have anything named "write".
Update
I just read your error message more carefully. Are you sure you correctly converted your data to a table? Here are some examples from the r2016a documentation,
dpb
dpb el 24 de Ag. de 2020
Editada: dpb el 24 de Ag. de 2020
Have to show us your code where tried to create the table -- you would need something like
tCD=array2table(CalibratedData,'VariableNames',names);
to create the four variables in the table instead of just one array that table would do.
Will work...alternatively,
fmt=[repmat('%s ',1,numel(names)-1) '%s\n'];
fid=fopen(SaveName,'w'); % create the file for write
fprintf(fid,fmt,names{:}); % note the {} to dereference cellstr to char strings
fid=fclose(fid); % close the file w/ header
save(SaveName, 'calibratedData', '-ASCII' '-append');
is a little more code once but will be quite a bit quicker.
After all these years, TMW still doesn't have decent tools to handle outputting cell strings or the new string class...
Adam Danz
Adam Danz el 24 de Ag. de 2020
I like the fprintf option.
dpb
dpb el 24 de Ag. de 2020
Editada: dpb el 25 de Ag. de 2020
At that point, may as well just go ahead and write the whole array...one more format string and an fprintf...
fmt1=[repmat('%s ',1,numel(names)-1) '%s\n'];
fmt2=[repmat('%f ',1,numel(names)-1) '%f\n'];
fid=fopen(SaveName,'w'); % create the file for write
fprintf(fid,fmt1,names{:}); % note the {} to dereference cellstr to char strings
fprintf(fid,fmt2,CalibratedData.'); % note the .' to write in row-major order to file
fid=fclose(fid); % close the file w/ header
Dorsa Mir Norouzi
Dorsa Mir Norouzi el 25 de Ag. de 2020
Ah thank you so much!!!! The fprintf option worked best. I seriously appreciate it!!!
Dorsa Mir Norouzi
Dorsa Mir Norouzi el 25 de Ag. de 2020
So I have one more question, when I look at the text file now, at a certain point (about halfway through) the numerical data gets shifted to the right. Normally this would be fine, however when I try to import the text file into an excel sheet to graph, the data isn't aligned properly. How can I fix this?
Dorsa Mir Norouzi
Dorsa Mir Norouzi el 25 de Ag. de 2020
Editada: Dorsa Mir Norouzi el 25 de Ag. de 2020
Actually, ^^ you can disregard that part. I increased the field width and it worked. The issue now is that the last two columns are merging together and the headers aren't aligned with the data.. I've attached a photo to show. This is the code now:
function calibratedData = applyCal(fname,Ey,components,rawData,Calib)
% applies calibration (gain and shift) to raw data; function returns
% calibrated data ONLY for 'components'!
calibratedData = [];
for i = find(components)
calibratedData(:,Ey(i).datacolumn) = ( rawData(:,Ey(i).datacolumn) - Calib(1,Ey(i).datacolumn) ) * Calib(2,Ey(i).datacolumn);
end
s = strtok(fname, '.');
SaveName = [s, datestr(now, ' yyyymmddTHHMMSS'),' calibrated.txt'];
names={'Blank','LE Horizontal','LE Vertical','RE Horizontal','RE Vertical'};
fmt1=[repmat('%15s ',1,numel(names)-1) '%s\n'];
fmt2=[repmat('%15e ',1,numel(names)-1) '%f\n'];
fid=fopen(SaveName,'w'); % create the file for write
fprintf(fid,fmt1,names{:}); % note the {} to dereference cellstr to char strings
fprintf(fid,fmt2,calibratedData.'); % note the .' to write in row-major order to file
fid=fclose(fid); % close the file w/ header
save(SaveName, 'calibratedData', '-ASCII', '-append');
end
This also ends up happening in the file: I should only have 108766 samples in this file, but there are more samples when I use this new code? And the new samples have extra digits which throws off the entire alignmend. Sorry for so many edits, I'm just trying to figure out what's going on and update this as I go.
Okay, last update. So looks like the solution was much more simple than I thought... Here is the final code that ended up working for me. Thank you again for all your help, it was very beneficial!!
function calibratedData = applyCal(fname,Ey,components,rawData,Calib)
% applies calibration (gain and shift) to raw data; function returns
% calibrated data ONLY for 'components'!
calibratedData = [];
for i = find(components)
calibratedData(:,Ey(i).datacolumn) = ( rawData(:,Ey(i).datacolumn) - Calib(1,Ey(i).datacolumn) ) * Calib(2,Ey(i).datacolumn);
end
s = strtok(fname,'.');
SaveName = [s, datestr(now, ' yyyymmddTHHMMSS'),' calibrated.txt'];
save (SaveName, 'calibratedData', '-ASCII');
fid=fopen(SaveName,'w'); % create the file for write
fprintf(fid,'%15s %15s %15s %15s %15s\n', 'blank', 'LEH', 'LEV', 'REH', 'REV');
fid=fclose(fid); % close the file w/ header
save(SaveName, 'calibratedData', '-ASCII', '-append');
end
dpb
dpb el 25 de Ag. de 2020
names={'Blank','LE Horizontal','LE Vertical','RE Horizontal','RE Vertical'};
fmt1=[repmat('%15s ',1,numel(names)-1) '%s\n'];
fmt2=[repmat('%15e ',1,numel(names)-1) '%f\n'];
The format width parameter is missing on the last element for each -- there are N-1 w/ trailing blank and one w/o. If you use the width parameter, then you can change that...
fmt1=[repmat('%15s ',1,numel(names)) '\n'];
fmt2=[repmat('%15e ',1,numel(names)) '\n'];
In the remainder
...
fprintf(fid,fmt2,calibratedData.'); % note the .' to write in row-major order to file
fid=fclose(fid); % close the file w/ header
save(SaveName, 'calibratedData', '-ASCII', '-append');
you write the data array twice -- once w/ fprintf with the width specified with fmt2 format string and then again you append the data to the file with save with the default format it uses. Use one but only one; I would recommend fprintf over the save .... -append route.

Iniciar sesión para comentar.

Más respuestas (0)

Productos

Versión

R2016a

Etiquetas

Preguntada:

el 24 de Ag. de 2020

Comentada:

dpb
el 25 de Ag. de 2020

Community Treasure Hunt

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

Start Hunting!

Translated by