I need to create few file ".txt" in Matlab and I want that each file has a different name, depending on a variable.
I have the variable choose_pol that can assume different values (1, 2, 3 and so on) and for each one I need a different file.
Right now I'm using dlmwrite (file.txt, THETA) to save what I have inside the matrix THETA in file.txt. Now since THETA changes depending on this variable choose_pol I whant to save the file depending on what I choose.
Then in an another script I need to read the txt file still depending on what I need. How can I do it?
Use sprintf to create a string from a variable:
filenames = {'ABC', 'DEFG'};
choose_pol = 2;
dlmwrite(sprintf('%s.txt',filenames{choose_pol}), THETA)
Related
I want to read data from a .m MATLAB file which is saved in my directory. However, when I used load('filename.m'), I get is a structure of size 1*1 and the 3320*9 matrix is within that structure file. How can I read it directly as a 3320*9 matrix?
You can get the desired behavior, if you're allowed to modify your save function.
Z = rand(10)
save('test.dat','Z','-ascii')
The ascii format is key, because Matlab allows a load directly to a variable:
test = load('test.dat','Z')
I have a MATLAB script which creates an matrix, 'newmatrix', and exports it as matrix.txt:
save -ascii matrix.txt newmatrix
In my script I also calculate the distance between certain elements of the matrix, as the size of the matrix depends on a variable 'width' which I specify in the script.
width = max(newmatrix(:,5)) - min(newmatrix(:,5))
x_vector = width + 2
And the variable x_vector is defined as width + 2
I want to know is it possible to export x_vector, labelling it as, eg my_vector $x_vector so that "my_vector 7.3" will be produced when the value of x_vector is equal to 7.3
I have tried:
save -ascii 'my_vector' + x_vector
But receive the following errors:
warning: save: no such variable +
warning: no such variable 'my_vector'
Three things:
1) I prefer to use functional form of the calls so that you can pass in variables rather than static strings.
save -ascii matrix.txt newmatrix
is equivalent to:
save('-ascii','matrix.txt','newmatrix')
In other words, in the first form all inputs get treated as string inputs to the function.
2) You can't add character arrays in Matlab. Rather you concatenate them or use sprintf.
name = sprintf('my_vector_%g',x_vector);
save('-ascii',name)
Note by using the functional form we can now pass in a variable. Note however this won't work because name should be either a valid option or a variable, and my_vector_7.3 isn't either.
3) I'm not entirely sure what you're asking, but I think you want the text file to say "my_vector 7.3". I don't think -ascii supports strings .... You could write something using fprintf.
fid = fopen('matrix.txt','w');
fprintf(fid,mat2str(new_matrix));
fprintf(fid,'\n');
fprintf(fid,'my_vector %g',x_vector);
fclose(fid);
new MATLAB user here so apologies if this seems like a silly question. I have the following list of variables (doubles) in my workspace:
E1_01Strain E1_06Strain E1_07Strain E1_08Strain E1_09Strain E1_10Strain
E1_01Stress E1_06Stress E1_07Stress E1_08Stress E1_09Stress E1_10Stress
These are lists of numbers. I would like to remove the last n elements from each variable. I can do it with the command
E1_01Strain = E1_01Strain(1:end-100)
but it's impractical because later I'm going to have to do it on many, many more similar variables. Therefore I wanted to write a function that accepts as inputs a list of the workspace variables (as in, I highlight the variables I want and drag and drop into the function input) and removes from each one n elements.
I understand that I can write a function like this:
function [X1, X2, X3, X4] = Remove_n_elements[n, X1, X2, X3, X4]
X1 = X1(1:end-100);
X2 = X2(1:end-100);
X3 = X3(1:end-100);
X4= X4(1:end-100);
end
but that would mean that I would have to change the number of inputs, outputs, and the lines of code in the function every time. I'm sure there's a better way to do it but I can't figure it out.
I keep thinking that there might be a way to do it by looping over all the inputs but I can't get it to work since (as far as I know) I need to create a list of the inputs and then the operation is performed only on the elements of that list, not the inputs themselves.
I was looking at Passing A Variable Number of Arguments into a Function and from that using inputParser from https://www.mathworks.com/help/matlab/matlab_prog/parse-function-inputs.html but since I'm new to MATLAB I'm not sure how to use it for my case.
I used the code provided by il_raffa for a bit but followed his advice and went back and reconsidered how the script functions. After some more digging I wrote the following script that does exactly what I need. This script extracts the columns des_cols from all .csv files in a folder and plots them together. It then makes another plot of the averages.
files = dir('*.csv'); % navigate to the folder that you want to run the script on in MATLAB
avgStress = [];
avgStrain = [];
set(groot, 'DefaultLegendInterpreter', 'none') % the names of my .csv files have underscores that I want to see in the legend, if you don't want this then comment this line
hold on; %comment this and hold off further down if you want separate plots for every .csv
for file = files'
csv = xlsread(file.name);
[n,s,r] = xlsread(file.name);
des_cols = {'Stress','Ext.1(Strain)'}; % type here the names of the columns you want to extract
colhdrs = s(2,:);
[~,ia] = intersect(colhdrs, des_cols);
colnrs = flipud(ia);
file.name = n(:, colnrs);
file.name = file.name(1:end-600,:); % I wanted to remove the last 600 rows but if you want them all, remove the -600
plot(file.name(:,2),file.name(:,1),'DisplayName',s{1,1});
avgStress = [avgStress file.name(1:1500,1)]; % calculates the average stress for the first 1500 points, you can change it to whatever you want
avgStrain = [avgStrain file.name(1:1500,2)];
end
ylabel({'Stress (MPa)'}); % y-axis label
xlabel({'Strain (%)'}); %x-axis label
title({'E_2'}); % title of the plot
legend('show');
hold off; % commment this if you want different plots for all .csv files
avgStress = mean(avgStress,2);
avgStrain = mean(avgStrain,2);
plot(avgStrain,avgStress);
This creates two plots, one with all the raw data and another with just the averages. I hope this helps anyone that might have a similar issue.
The best thing you can do is to review the architecture of your SW in order to avoid the needs to perform such operations on the Workspace variables.
That is: how those variables are created? Are these variables loaded from a ".mat" file? etc.
Anyway, in order to avoid using the eval function and given your situation, a possible approach could be:
identify the names of the varailbes by using the function who. You can specify in the call to who the root name of the varaibles and use the * as, for example, who('E1*'). Make sure it fit wiht the desired variables. You can also use regexp to better refine the selection of the variables
save these varaibles in a temporary .mat file: the name (including the path of the temporary file can be created with the function tempname
load the temporary .mat file: this will create a struct in the Workspace whose fields are the variables you want to midify
call the function to remove the undesired elements form the fields of the struct. The function have to return the updated struct
save the updated struct in the temporary file
load again the temporary file by specifying the option -struct which allows loading the content of the file as single varaibles
The function to remove the undesired elements can be made as follows:
get the nams of the struct's fields by using the function fieldnames
loop over the filed of the struct by using the dynamic field names property
remove the undesired elements form the fields
return the updated struct
A possible implementatin could be:
Code "before" the call to the function
% Get the names of the variables
list_var=who('E1*')
% Define the name of a temporary ".mat" file
tmp_file=tempname
% Save the variables in the temporary ".mat" file
save(tmp_file,list_var{:});
% Load the variables in a struct
sel_vars=load(tmp_file);
% Call the function to remove the elements
out_str=Remove_n_elements(8,sel_vars)
Function to remove the undesired elements
function sel_vars=Remove_n_elements(n,sel_vars)
% Get the names of the fields of the struct
var_names=fieldnames(sel_vars)
% Loop over the fields and remove the undesired elements
for i=1:length(var_names)
sel_vars.(var_names{i})=sel_vars.(var_names{i})(1:end-n)
end
Code "after" the call to the function
% Save the updated struct in the temporary ".mat" file
save(tmp_file,'-struct','out_str')
% Load the updated struct as separate variables
load(tmp_file)
I have 2 matlab programs : prog1.m and prog2.m
I have to use a 2-D matrix M in both programs.
I have loaded the matrix in prog1.m (manually from a TEXT FILE).
I have to run both the programs ~100 times (for different matrix each time) . So now i have ran prog1.m 100 times , every time with different matrix .
Now is turn of prog2.m but i don't want to load matrix manually again.
I have the saved (100 copies of) prog1.m which contains M to be used in prog2.m also . Is there a method to load M from prog2.m to prog1.m ?
I want to add some code in prog2.m which automatically loads M from prog1.m .
PS: I am very new to MATLAB
If prog1 and prog2 are not already functions, rewrite them as functions. For example, the first line in them may look like:
function [out1 out2] = prog1(M)
function out = prog2(M)
Then, write a third function which, given a filename, loads the data, calls prog1 and prog2 and optionally saves the data in an appropriate form (you can use fileparts and fullfile to automatically create a new filename based on the input - e.g. given data101.txt, return data101_proc.mat. Bare bones of such a function would be along these lines:
function M = prog3(fname)
M = load(fname); % or whatever method is required for loading this data
%call prog1 and prog2
[out1 out2] = prog1(M);
out3 = prog2(M);
%make new filename
[fpath,fname2,ext] = fileparts(fname);
fname_out = fullfile(fpath, [fname2,'_out','.mat']);
%save data - depends on what outputs are and what you need to do with them later
save(fname_out, 'out1','out2','out3','M');
end
Finally, as babaea mentioned, you can use ls or dir, make up a list of the files you want to use, and create a loop which calls the above function on each file in turn.
The most efficient way of doing what you want to do is to read directly from the text file using textscan:
http://www.mathworks.co.uk/help/matlab/ref/textscan.html
If the formatting in the text files are the same, you can read from one file at a time, do your process then change the name and run again.
You can make the process more automated by changing the name of the file from which data is read dynamically in a loop around your main program. But the way to do this depends on the name of the text files.
I am quite new to data analysis, so if this is a rookie question, I'm sorry, I am learning as I go.
I have just started doing some work in variable star astronomy. I have about 100 files for every night of observation that all contain the same basic information (star coordinates, magnitude, etc.). I am loading all of the files into my workspace as arrays using a for-loop
files = dir('*.out');
for i=1:length(files)
eval(['load ' files(i).name ' -ascii']);
end
I'm only really interested in two columns in each file. Is there a way to extract a column and set it to a vector while this for-loop is running? I'm sure that it's possible, but the actual syntax for it is escaping me.
try using load as a function and save it's output to a variable
files = dir('*.out');
twoCols = {};
for ii=1:length(files)
data = load( files(ii).name, '-ascii' ); % load file into "data"
twoCols{ii} = data(:,1:2); % take only two columns
end
Now variable twoCols holds the two columns of each file in a different cell.
You have to assign the load result to a new variable. Then if lets say your variable is starsInfo you can use
onlyTwoFirst = starsInfo(:,1:2)
That means take all the rows, but only columns 1 and 2.