Saving the selected .mat file and write it into csv

Hello there,
I was implmenting something similar from this post: https://www.mathworks.com/matlabcentral/answers/317297-uigetfile-load-m-file-variables-into-workspace and I want to get the selected .mat file and write it into csv. I have the following but I have the problem of saving it into .csv file
[baseFileName, folder] = uigetfile('*.mat');
fullFileName = fullfile(folder, baseFileName);
if exist(fullFileName, 'file')
storedStructure = load(fullFileName);
else
warningMessage = sprintf('Warning: mat file does not exist:\n%s', fullFileName);
uiwait(errordlg(warningMessage));
return;
end
cHeader = {'x' 'y' 'z'}; %dummy header
commaHeader = [cHeader;repmat({','},1,numel(cHeader))]; %insert commaas
commaHeader = commaHeader(:)';
textHeader = cell2mat(commaHeader); %cHeader in text with commas
%write header to file
%write data and save it to .csv
fid = fopen(fullFileName,'w');
fprintf(fid,'%s \n',textHeader);
fclose(fid);
dlmwrite(fullFileName,storedStructure.data,'-append');
I think I have problem in the secotion of %write data and save it to .csv using fullFileName. I do not know how to do it properly since we do not have one fixed file to write into. Thanks!

 採用された回答

Guillaume
Guillaume 2020 年 2 月 6 日

1 投票

Assuming that storedStructure.data is a matrix with 3 columns, the simplest way to save to csv is with:
writetable(array2table(storedStructure.data, 'VariableNames', {'x', 'y', 'z'}), fullfilename, 'FileType', 'text');
Note that I would recommend changing the extension of the filename from .mat to .csv so that it's not misleading.

18 件のコメント

steamrice
steamrice 2020 年 2 月 6 日
Hello, thanks for the response. Do you mean replace
cHeader = {'x' 'y' 'z'}; %dummy header
commaHeader = [cHeader;repmat({','},1,numel(cHeader))]; %insert commaas
commaHeader = commaHeader(:)';
textHeader = cell2mat(commaHeader); %cHeader in text with commas
%write header to file
%write data and save it to .csv
fid = fopen(fullFileName,'w');
fprintf(fid,'%s \n',textHeader);
fclose(fid);
dlmwrite(fullFileName,storedStructure.data,'-append');
to
writetable(array2table(storedStructure.data, 'VariableNames', {'x', 'y', 'z'}), fullfilename, 'FileType', 'text');
I have tried that but it gives me "Unrecognized file extension '.mat'. Use the 'FileType' parameter to specify the file type."
Guillaume
Guillaume 2020 年 2 月 6 日
"Do you mean replace ..."
Exactly, it's so much simpler if you use tables.
"I have tried that but it gives me "Unrecognized file extension '.mat'. Use the 'FileType' parameter to specify the file type."
You can't have tried that exactly, since the code you show has the 'FileType' parameter that the error message tells you to use. However, as I wrote, I would strongly recommend changing the extension to .csv (which means you wouldn't have to bother with the 'FileType' parameter) since using a .mat extension for what is a csv file is very misleading.
steamrice
steamrice 2020 年 2 月 6 日
Use the 'FileType' parameter to specify the file type."
So I would do: FileType to .mat ?
" I would strongly recommend changing the extension to .csv (which means you wouldn't have to bother with the 'FileType' parameter) since using a .mat extension for what is a csv file is very misleading."
I am not too sure what do you mean by that? I was thinking to have my .mat file, do some analsis and write the result as .csv file.
Thanks for your patience as I am a bit new to working with this concept
Guillaume
Guillaume 2020 年 2 月 6 日
"So I would do: FileType to .mat ?"
No, 'FileType', 'text' exactly as I wrote in my answer. It tells writetable to write the file as text (== csv) despite the file extension.
A .mat file is not a csv file. It's matlab own format, it's binary. The two are completely different so if you're saving a csv file you shouldn't use the extension .mat.
steamrice
steamrice 2020 年 2 月 7 日
Thanks for the reponse! I followed your advice and the porgram runs but I do not see where the csv file is saved? Thanks for your time!
Walter Roberson
Walter Roberson 2020 年 2 月 7 日
strrep(fullFileName, '.mat', '.csv')
and use that as the destination file name
steamrice
steamrice 2020 年 2 月 7 日
@Walter Roberson Hello, I put that after writetable but the error comes up agian
Unable to read MAT-file C:\Users\..mat. Not a
binary MAT-file. Try load -ASCII to read as text.
Guillaume
Guillaume 2020 年 2 月 7 日
編集済み: Guillaume 2020 年 2 月 7 日
"I followed your advice and the porgram runs but I do not see where the csv file is saved"
This is a strange statement, the file will be in the the exact location specified by fullFileName. You've specified that location so you should know where it is.
" but the error comes up agian"
No, it's a completely different error, and one that occurs when you try to load the file. As I keep saying a csv file is not a mat file, they're two very different things for which you use different functions for reading and writing. You may be able to load the file with
load(nameoffile, '-ascii')
but you should use the proper functions for this:
readtable(nameoffile)
%or to get a matrix, but in this case there was no point writing the header:
readmatrix(nameoffile)
%or using deprecated functions:
csvread(nameoffile)
%or
dlmread(nameoffile)
steamrice
steamrice 2020 年 2 月 7 日
Thanks for the reposne. Can you direct me a liitle bit on how your suggestion can be implemented together with what I have? Should I try something like:
[baseFileName, folder] = uigetfile('*.mat');
fullFileName = fullfile(folder, baseFileName);
if exist(fullFileName, 'file')
storedStructure = load(fullFileName);
else
warningMessage = sprintf('Warning: mat file does not exist:\n%s', fullFileName);
uiwait(errordlg(warningMessage));
return;
end
csvread(fullFileName)
%or
dlmread(fullFileName)
I want to allow the user to selected the desired .mat file and then after write it into .csv . I thought I could just use "load" to load .mat?
Thanks
Guillaume
Guillaume 2020 年 2 月 7 日
I think we're misunderstanding each other.
Your initial code loads a file (with load which is correct). Then with my answer you're saving part of it as a csv file (with writetable).
Then, at some point you've tried to load that csv file. That's a different piece of code which I don't think you've shown. csv files are loaded with any of the functions I've listed, mat files with load indeed.
The other possibility is that your mention of csv is a red herring and you wanted to save your data as a mat file all along (which you could read with load). If you wanted to save the field data of storedStructure as a mat file, then replace my original answer with
save(fullfilename, '-struct', 'StoredStructure', 'data');
steamrice
steamrice 2020 年 2 月 7 日
編集済み: steamrice 2020 年 2 月 7 日
I am so sorry for miscommunication.
I am loading .mat file and want to save it as .csv! I think your original answer was helping?
But I think with writetable, I still do not see where the .csv file was saved (the program runs with no error)
steamrice
steamrice 2020 年 2 月 7 日
I think maybe I understand why this error is coming from
Unable to read MAT-file C:\Users\..mat. Not a
binary MAT-file. Try load -ASCII to read as text.
If I use writetable, it will rewrite my original .mat file into .csv file right? Beacause what I am seeing right now is the the code runs the first time with no error. However, if I run the second time, the above error comes back agian!
Sorry for not being so clear. I think my goal for now is to load my .mat file data and (potentially after some anaylsis) save it into a new .csv file. Do you think that's possible with my current setup? Thanks
Guillaume
Guillaume 2020 年 2 月 7 日
Well, yes if you load a mat file, save it as a csv then try to reload that csv as a mat file, it's not going to work. The second time round it's no longer a mat file.
Indeed, the best thing is to save the csv file as a new file, not a replacement for the original mat file. Hence why I said to change the extension.
csvfilename = strrep(fullFileName, '.mat', '.csv');
writetable(array2table(storedStructure.data, 'VariableNames', {'x', 'y', 'z'}), csvfilename));
would save the file in the exact same location as the original mat file, with the same name, except for extension, which is now csv.
steamrice
steamrice 2020 年 2 月 7 日
Thanks for the help. Just a little bit extension. Are the VariableNames or header that I see in the .csv (or excel) followed by the numbers of the table? I have 3 column now so for x, y, z it would work. But if I want to add additional hearder: x,y,z,a, b, c it will not work? (I tried an error showed up)
The VariableNames property must contain one name for each variable in the table.
I am thinking to output the user input into the same .csv as well. Thanks for your time again
steamrice
steamrice 2020 年 2 月 9 日
Should I make a new post here again if I have more questions?
Walter Roberson
Walter Roberson 2020 年 2 月 9 日
writetable(array2table(storedStructure.data, 'VariableNames', {'x', 'y', 'z'}), csvfilename));
The VariableNames set there has 3 elements. That command is only suitable for an array that has exactly 3 columns. For six columns, the cell array of character vectors would need 6 entries.
You can break the code up into several statements, like
T = array2table(storedStructure.data);
T.Properties.VariableNames = cell array with as many entries as data had columns
writetable(T, csvfilename)
steamrice
steamrice 2020 年 2 月 9 日
@Walter Roberson I am still only work with the number of columns I have (according to my data). Other than that, its it possbile to save out the user input (from prompt) and write it into the same .csv?

サインインしてコメントする。

その他の回答 (1 件)

steamrice
steamrice 2020 年 2 月 10 日

0 投票

Thanks for the response!
I think you mentioned, "I need to emphasize that this cannot be used to add new columns to a csv file."
Does that mean its not possbile to combine the user input from prompt with the after-data-anaylsis into the same .csv?

4 件のコメント

Guillaume
Guillaume 2020 年 2 月 10 日
You may want to start a new question, explaining a bit more what it is you want doing (start point and desired end point).
Walter Roberson
Walter Roberson 2020 年 2 月 10 日
編集済み: Walter Roberson 2020 年 2 月 10 日
Does that mean its not possbile to combine the user input from prompt with the after-data-anaylsis into the same .csv?
No, it does not mean that.
If you have an existing .csv file and you want to add new rows to it, then you can do that by appending to the file without changing what is already there.
If you have an existing .csv file and you want to add new columns to it, then there is no way to do that without changing what is already there. None of the Mathworks-supplied functions can add new columns to a .csv file: they can only add new rows or they can rewrite the entire file, destroying whatever is currently in it.
In other words, if you want to add new columns to a .csv, then what you need to do is read in all of the existing data from the .csv, and add more columns to what you read in, and then write the old data together with the new data overtop of the file.
It is simply not technically possible to add new columns to a text file without rewriting from the end of the old first line completely through to the end of the file -- but by the same measure, if you do bother to read in the existing data, you can certainly write it out with new data as well.
steamrice
steamrice 2020 年 2 月 10 日
Question: If adding new row, wouldn't it affect my data (three column) as well?
In addition, would you mind direct me if I want to try this method?
"if you want to add new columns to a .csv, then what you need to do is read in all of the existing data from the .csv, and add more columns to what you read in, and then write the old data together with the new data overtop of the file."
Guillaume
Guillaume 2020 年 2 月 10 日
As said, you'd be better off starting a new question. You'd likely get more contributors.
"If adding new row, wouldn't it affect my data"
Not sure what you mean by that. new rows are added to the end of the file by using the OS file append mode. This does not touch data earlier in the file.
"would you mind direct me if I want to try [adding new columns]"
Here you need to a number of difficulties. Do you need to preserve the exact text formatting of the earlier columns, including number format, separator(s) (type and number if using spaces/tabs for example), etc.? Do you have to detect the formatting or can your code just assume the formatting?
The simplest way, which may not preserve the formatting is to read your file with your favorite csv reading function (readmatrix, readtable, csvread, dlmread, importdata (avoid that one)), append your new columns to the data and rewrite with the matching function to the one you used to read (writematrix, writetable, csvwrite, dlmwrite).
olddata = readmatrix(somefile);
appended = [olddata, newdata]; %newdata must be a matrix with as many rows as olddata
writematrix(appended, somenewfile);
If you need to preserve formatting and autodetect the formatting, it could be significantly more complicated.

サインインしてコメントする。

製品

タグ

質問済み:

2020 年 2 月 6 日

コメント済み:

2020 年 2 月 10 日

Community Treasure Hunt

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

Start Hunting!

Translated by