I'm trying to change output names using for in Matlab. I'm reading daily files, so I'd like the outputs to also have the day printed on their name. This is a simplification of what I've got so far:
day=['1','2','3','4','5'];
for i=1:length(day)
namefile=['datafromday',num2str(day(i)),'.nc'];
[var1,var2,var3]=read(namefile);
var1_*=var1;
var2_*=var2;
var3_*=var3;
end
The * marks where I want to have the day number on. I've tried the same combination as in namefile but was unsuccessful.
Any ideas? Thank you!
I suggest you use a 2D cell array instead of separate variables. First index of the cell array will correspond to day, second will correspond to namefile. (Also, don't use var as a variable name, as there is a function with that name).
day = ['1','2','3','4','5'];
vars = cell(numel(day),3); %// change "3" as needed
for i = 1:length(day)
namefile = ['datafromday',num2str(day(i)),'.nc'];
[vars{i,:}] = read(namefile);
%// Now the file names are in vars{i,1}, vars{i,2} etc
end
Related
I want to create a variable called 'flag_artifact' where certain subjects from my dataset (for whom I know have bad quality images) are coded as e.g., 1. My dataset is stored in a table T with a certain number of rows and 'subject' is the 1st column in the table.
I managed to do it by creating a for loop. Surely there is a more efficient way to do this by perhaps directly creating the variable and using less lines of code? Could anyone give some advice?
Thank you very much! Here is what I have:
flag_artifact = {'T_300'}; %flagging subject number 300 for example
for i = 1:size(T,1)
if isequal(table2cell(T(i, 1)), flag_artifact)
T(i, 1) = {'1'};
end
end
However, when creating the variable flag_artifact = {'T_300'}, I would like it to include more than one subject. I tried using flag_artifact = {'T_300'}; {'T_301'}, as well as flag_artifact = {'T_300', 'T_301'} but it doesn't work because these subject identifiers do not get replaced with 1s.
I have a list of .txt datafiles to import. Suppose they are called like that
file100data.txt file101data.txt ... file109data.txt I want to import them all using readtable.
I tried using the for to specify a vector a = [0:9] through which matlab could loop the readtable command but I cannot make it work.
for a = [0:9]
T_a_ = readtable('file10_a_data.txt')
end
I know I cannot just put _a_ where I want the vector to loop through, so my question is how can I actually do it?
Thank you in advance!
Here is a solution that should work even if you have missing files in your folder (e.g. you have file100data.txt to file107data.txt, but you are missing file file108data.txt and file109data.txt):
files=dir('file10*data.txt'); %list all data files in your folder
nof=size(files,1); %number of files
for i=1:nof %loop over the number of files
table_index=files(i).name(7) %recover table index from data filename
eval(sprintf('T%s = readtable(files(i).name)', table_index)); %read table
end
Now, please note that is it generally regarded as poor practice to dynamically name variables in Matlab (see this post for example). You may want to resort to structures or cells to store your data.
You need to convert the value of a into a string and combine strings together, like this:
Tables = struct();
for a = 0:9
% note: using dynamic structure field names to store the imported tables
fname = ['file10_' num2str(a) '_data'];
Tables.(fname) = readtable([fname '.txt']);
end
I have code that creates a portfolio in matlab by merging two time series. How do I retrieve a vector of Headers for the funds such that I get a vector with the fund names from 'Port'?
Fund1ts=fints(Fund1Dates,Fund1Data,'Fund1');
Fund2ts=fints(Fund2Dates,Fund2Data,'Fund2');
%CREATE PORTFOLIO
Port=merge(Fund1ts,Fund2ts,'DateSetMethod','Intersection');
If you look at Port in the Command Window they are present. However if you open Port from Workspace Window then only the data exists hence my problem in retrieving it.
Thank you.
As Hugh Nolan also suggested in a comment, this should get you the names you are after:
fnames = fieldnames(Port, 1)
From the documentation:
fnames = fieldnames(tsobj, srsnameonly) returns field names depending upon the setting of srsnameonly. If srsnameonly is 0, the function returns all field names, including the common fields: desc, freq, dates, and times. If srsnameonly is set to 1, fieldnames returns only the data series in fnames.
Hence the 1 in the code-snippet above. It will return only Fund1 and Fund2.
Edit
It appears that there are two functions called fieldnames in Matlab:
The 'standard' function fieldnames:
names = fieldnames(s)
names = fieldnames(obj)
names = fieldnames(obj,'-full')
The function fieldnames which is part of the Financial Toolbox:
fnames = fieldnames(tsobj)
fnames = fieldnames(tsobj, srsnameonly)
If called with one input argument, they both operate similarly. However, for future readers of this answer: The particular answer given above works only for the Financial Toolbox-version of the function.
I want to create a structure with a variable name in a matlab script. The idea is to extract a part of an input string filled by the user and to create a structure with this name. For example:
CompleteCaseName = input('s');
USER WRITES '2013-06-12_test001_blabla';
CompleteCaseName = '2013-06-12_test001_blabla'
casename(12:18) = struct('x','y','z');
In this example, casename(12:18) gives me the result test001.
I would like to do this to allow me to compare easily two cases by importing the results of each case successively. So I could write, for instance :
plot(test001.x,test001.y,test002.x,test002.y);
The problem is that the line casename(12:18) = struct('x','y','z'); is invalid for Matlab because it makes me change a string to a struct. All the examples I find with struct are based on a definition like
S = struct('x','y','z');
And I can't find a way to make a dynamical name for S based on a string.
I hope someone understood what I write :) I checked on the FAQ and with Google but I wasn't able to find the same problem.
Use a structure with a dynamic field name.
For example,
mydata.(casename(12:18)) = struct;
will give you a struct mydata with a field test001.
You can then later add your x, y, z fields to this.
You can use the fields later either by mydata.test001.x, or by mydata.(casename(12:18)).x.
If at all possible, try to stay away from using eval, as another answer suggests. It makes things very difficult to debug, and the example given there, which directly evals user input:
eval('%s = struct(''x'',''y'',''z'');',casename(12:18));
is even a security risk - what happens if the user types in a string where the selected characters are system(''rm -r /''); a? Something bad, that's what.
As I already commented, the best case scenario is when all your x and y vectors have same length. In this case you can store all data from the different files into 2 matrices and call plot(x,y) to plot each column as a series.
Alternatively, you can use a cell array such that:
c = cell(2,nufiles);
for ii = 1:numfiles
c{1,ii} = import x data from file ii
c{2,ii} = import y data from file ii
end
plot(c{:})
A structure, on the other hand
s.('test001').x = ...
s.('test001').y = ...
Use eval:
eval(sprintf('%s = struct(''x'',''y'',''z'');',casename(12:18)));
Edit: apologies, forgot the sprintf.
I have a bunch of Excel data, called "1.xls", "2.xls"... until "15.xls", each with 141x44 sets of data. I am using the dir function to import the data into MATLAB.
Here I am importing the first and second columns from each file into A and B matrix.
prob15 = dir(fullfile('C:\Users\Bo Sun\Documents\MATLAB\prob15'),'.xls');
global A B
A=zeros(141,length(prob15));
B=zeros(141,length(prob15));
for i=1:length(prob15)
A(:,i) = xlsread(prob15(i).name,'A:A');
B(:,i) = xlsread(prob15(i).name,'B:B');
end
My problem is, when I use the dir command, for some reason MATLAB missorts the data, in that the ascending order of the prob15 structure array will be "1.xls", "10.xls", "11.xls"... instead of normal ascending numerical order ("1.xls", "2.xls, ...). Anyone know how I could fix this? Thanks.
The order you are seeing is called ascii-betical order and is the normal sorting order for all kinds of utilities, and evidently your OS directory listing program as well, since matlab just farms this command out to the OS.
If you want a numerical sort, you can convert the filename strings to numbers and sort those. Before I wrote it myself some light googling yielded this which you can easily adapt to your problem:
list = dir(fullfile(cd, '*.mat'));
name = {list.name};
str = sprintf('%s#', name{:});
num = sscanf(str, 'r_%d.mat#');
[dummy, index] = sort(num);
name = name(index);