I am creating a matlab application that is analyzing data on a daily basis.
The data is read in from an csv file using xlsread()
[num, weather, raw]=xlsread('weather.xlsx');
% weather.xlsx is a spreadsheet that holds a list of other files (csv) i
% want to process
for i = 1:length(weather)
fn = [char(weather(i)) '.csv'];
% now read in the weather file, get data from the local weather files
fnOpen = xlsread(fn);
% now process the file to save out the .mat file with the location name
% for example, one file is dallasTX, so I would like that file to be
% saved as dallasTx.mat
% the next is denverCO, and so denverCO.mat, and so on.
% but if I try...
fnSave=[char(weather(i)) '.mat'] ;
save(fnSave, fnOpen) % this doesn't work
% I will be doing quite a bit of processing of the data in another
% application that will open each individual .mat file
end
++++++++++++++
Sorry about not providing the full information.
The error I get when I do the above is:
Error using save
Argument must contain a string.
And Xiangru and Wolfie, the save(fnSave, 'fnOpen') works as you suggested it would. Now I have a dallasTX.mat file, and the variable name inside is fnOpen. I can work with this now.
Thanks for the quick response.
It would be helpful if you provide the error message when it doesn't work.
For this case, I think the problem is the syntax for save. You will need to do:
save(fnSave, 'fnOpen'); % note the quotes
Also, you may use weather{i} instead of char(weather(i)).
From the documentation, when using the command
save(filename, variables)
variables should be as described:
Names of variables to save, specified as one or more character vectors or strings. When using the command form of save, you do not need to enclose the input in single or double quotes. variables can be in one of the following forms.
This means you should use
save(fnSave, 'fnOpen');
Since you want to also use a file name stored in a variable, command syntax isn't ideal as you'd have to use eval. In this case the alternative option would be
eval(['save ', fnSave, ' fnOpen']);
If you had a fixed file name (for future reference), this would be simpler
save C:/User/Docs/MyFile.mat fnOpen
Related
Given that I write to a workbook, I currently kill all Excel processes so that my code works when I call it in a loop.
xlswrite(path,values);
system('taskkill /F /IM EXCEL.EXE');
This makes me unable to run the code while I am working in another Excel file. How do I make it so that Matlab terminates only the Excel processes that itself created?
This was a "feature" introduced somewhere around R2015b to speed up multiple writes to Excel... not very user/memory friendly!
The xlswrite documentation links to this MathWorks Support Answer to manually write to Excel using actxserver, you can then manually delete the COM object referencing Excel.
You can actually edit xlswrite and see that it uses matlab.io.internal.getExcelInstance, which does the same thing and creates a COM interface with actxserver.
A cheeky option would be to copy xlswrite, add the Excel variable it creates as an output, and Quit and delete it afterwards, as shown below. I don't advocate breaking any of The MathWorks' copyright ownership of that function.
A less cheeky option would be to create a comparable function based on the answer I linked above, for writing data only it would look something like this:
function xlswriteClean( File, Data, Range )
% XLSWRITECELAN writes data like XLSWRITE, but deletes the Excel instance!
% XLSWRITECELAN (FILE,DATA,RANGE) writes the variable in
% DATA to FILE, in the range specified by RANGE.
% RANGE is optional, defaults to "A1"
% Obtain the full path name of the file
% Could handle this more elegantly, i.e.
% this always assumes the current directory, but user might give a full path
file = fullfile(pwd, File);
% Open an ActiveX connection to Excel
h = actxserver('excel.application');
%Create a new work book (excel file)
wb = h.WorkBooks.Add();
% Select the appropriate range
if nargin < 3
Range = 'A1';
end
rng = h.Activesheet.get('Range', Range);
% Write the data to the range
rng.value = Data;
% Save the file with the given file name, close Excel
wb.SaveAs( File );
% Clean up - the point of this function
wb.Close;
h.Quit;
h.delete;
end
You can customise basically everything within the new Excel workbook using the COM object h, so you could add any functionality which you use in xlswrite like sheet naming etc.
You can start the excel process by powershell and get its process id then use the process id to kill the process:
[~, pid] = system('powershell (Start-Process excel.exe -passthru).Id');
% Do your work
% ...
system(['powershell Stop-Process -Id ' pid])
I have different mat files w/ distinct names. So I am using a function whose input is the mat file. I used "varargin" to enable the function to take different files.
function bestfunc(varargin)
data = load(varargin, '-mat');
end
when I try to call the function like
bestfunc('matrix777')
Matlabe comes up w/ this error:
Error using load
Argument must contain a string.
Any ideas?
you have to get the names of the files. You can use dir() to do that.
dir('*.mat') % will return information about all .mat files in the folder
The output is a struct with more information for each file. TO get the names try
names=struct2cell(dir('*.mat'));
names=names(1,:);
now names is a cellarray with the names of all *.mat files of your folder. TO load data from each go for
for i=1:length(names)
bestfun(names{i});
end
Since you're only passing one argument, you don't need varargin, which is used when you may have a variable number of arguments to a function.
Just use a normal variable name like matname:
function bestfunc(matname)
data = load(matname, '-mat');
end
Then call it as you did before:
bestfunc('matrix777')
My file contains text in first few lines and the data afterward. It looks like this -
#
SCALARS ESA FLOAT
LOOKUP_TABLE default
1.135409e-02
5.018007e-03
1.693268e-02
1.585292e-02
1.872202e-03
6.062706e-03
2.285194e-02
1.173866e-02
#
From this, how do i just obtain the data and store it to a variable in matlab ?
The textscan function will be quite useful here, and you can find a thorough introduction here: http://uk.mathworks.com/help/matlab/ref/textscan.html
Most of the MATLAB text import functions (including textscan) allow you to specify how many lines of text at the start of the file should be ignored, e.g.: 'HeaderLines',2 would be appropriate for your file.
An alternative method (such as if the header contains useful information is to read and store the header text:
fileID = fopen('testFile.txt'); % open connection to file
header = textscan(fileID,'%s',2,'delimiter','\n'); % read 2 header lines as strings
data = textscan(fileID,'%f','delimiter','\n'); % read till end of file as floats
fclose(fileID); % close connection to file
I have 31 models an I want to save each one in a specific file
this is my matlab function
formatspec='model%d'
for k = 1:length(libsvmFiles)
baseFileName = libsvmFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
[labels train]=libsvmread(fullFileName);
model=svmtrain(labels,train, '-t 2 -h 0');
file=sprintf(formatspec,k);
save file model;
but the problem is only the first file is saved and its name is 'file' tha's mean the value of the variable file is not evaluated
how can I solve this problem ?
As many Matlab functions, save can be used in function form (save(...)) or in command form (save ...). In the command form that you use, all the arguments are interpreted as strings. That means
save file model
is equivalent to
save('file', 'model')
For the second argument that is correct, because you want to refer to the variable with the name "model". For the first argument it is wrong, because you want to refer to the file name contained in the variable file. The correct syntax to use is therefore
save(file, 'model')
You're missing the parens for the save function. The model variable also needs to be listed as a string since you need to tell the save function the name of the variable, not the variable itself. See Matlab's documentation.
save(file, 'model');
Additionally you don't have an end to your for loop shown, which normally would just throw an error -- however later code might cause this loop to instead only run once. Otherwise you should check your libsvmFiles variable as it might be only length 1 or not be an array.
I think it would be useful, at least I find so, and I searched for but did not find anythign appropriate.
Supposing you have a set of lines that use stdout, or these lines are included in a function. Then I need to change the output stream to a file. But not with diary() and such.
Example:
ShowResults(...) % this is a function containing a lot of fprintf('asdasdasd', ...)
% which by default shows messages on monitor
then I need something like:
ShowResults(...) % this will now output to monitor
setOutputHandler(my_file_pointer); % setup redirection
ShowResults(...) % this will now output to the file
setOutputHandler(stdout);
or even better something like:
setOutputHandler(stdout, my_file_pointer);
ShowResults(...) % this will now output to the file and monitor at the same time
setOutputHandler(stdout);
Especially if you use fprintf in your function, the easiest would be to define an additional input that you'd use as first argument in each call to fprintf
By default, that additional input would be set to 0, which means fprintf prints to screen. Alternatively, you can pass a file identifier created by fopen to showResults, so that fprintf would write to file.
If that is infeasible, you can always use capturedOutput = evalc('showResults(...)'), which will capture all the outputs in an array, from which you'd write to file.