Create a list and append file names to this list - matlab

I am trying to append filenames in a directory to a list for later processing. The code below does not work.
files = dir( fullfile(home,'*.csv') );
files = {files.name}'; %'# file names
symbolsList = [];
filedata = cell(numel(files),1); %# store file contents
for i=1:numel(files)
[pathstr,name,ext] = fileparts(files{i});
symbolsList(end + 1) = name; % THIS GIVES ERROR
end

In your code, symbolsList will be interpreted as an array of characters. The statement where the error is appearing is interpreted as appending a single character to symbolsList. You are probably getting a subscript alignment mismatch because a name will most likely have more than one character, yet you are trying to fit many characters into a single spot in that array of characters. That's probably not what you want.
You want each "space" to have a name. Because each name will most likely not have the same amount of characters, you should probably use a cell array instead:
files = dir( fullfile(home,'*.csv') );
files = {files.name}'; %'# file names
symbolsList = cell(numel(files),1); %// Change
filedata = cell(numel(files),1); %# store file contents
for i=1:numel(files)
[pathstr,name,ext] = fileparts(files{i});
symbolsList{i} = name; %// Change
end
Take note that I've pre-allocated the cell array and for each file you want to look at, I've indexed into the right cell and placed the name there. This is preferred over concatenation primarily due to efficiency. To access the ith name, simply do:
name_to_choose = symbolsList{i};
Minor Note
filedata in your code isn't being used anywhere at all. Are you sure you put all of your code up?

Related

Matlab file name concatenation

%% File Names reading and label generation
dataFolder= 'allcontent';
fileNames = dir([dataFolder 'c*.*']);
lbl = sscanf(cat(1,'fileNames.name'),'co2%c%d.rd.%d');
status = lbl(1:3:end);
id = lbl(2:3:end);
ids = unique(id);
trial = lbl(3:3:end);
I want to concatenate the names of all the files in the folder titled all content , at the moment, matlab doesn't understand what allcontent is. Can someone help me get the contents of the folder ' all content' which are of the form 'c*.*' and then concatenate them?
You can use fullfile to concatenate paths in Matlab, i.e.
fileNames = dir(fullfile(dataFolder, 'c*.*'));
Also, I don't think fileNames.name should be in quotes. As #Wolfie mentioned, you can concatenate the filenames into a cell array using {fileNames.name}
filenames_array = {fileNames.name}
Then you can iterate over filenames_array using for or cellfun

Pull specific cells out of a cell array by comparing the last digit of their filename

I have a cell array of filenames - things like '20160303_144045_4.dat', '20160303_144045_5.dat', which I need to separate into separate arrays by the last digit before the '.dat'; one cell array of '...4.dat's, one of '...5.dat's, etc.
My code is below; it uses regex to split the file around the '.dat', reshapes a bit then regexes again to pull out the last number of the filename, builds a cell to store the filenames in then, and then I get a tad stuck. I have an array produced such as '1,0,1,0,1,0..' of required cell indexes which I thought might be trivial to pull out, but I'm struggling to get it to do what I want.
numFiles = length(sampleFile); %sampleFile is the input cell array
splitFiles = regexp(sampleFile,'.dat','split');
column = vertcat(splitFiles{:});
column = column(:,1);
splitNums = regexp(column,'_','split');
splitNums = splitNums(:,1);
column = vertcat(splitNums{:});
column = column(:,3);
column = cellfun(#str2double,column); %produces column array of values - 3,4,3,4,3,4, etc
uniqueVals = unique(column);
numChannels = length(uniqueVals);
fileNameCell = cell(ceil(numFiles/numChannels),numChannels);
for i = 1:numChannels
column(column ~= uniqueVals(i)) = 0;
column = column / uniqueVals(i); %e.g. 1,0,1,0,1,0
%fileNameCell(i)
end
I feel there should be an easier way than my hodge-podge of code, and I don't want to throw together a ton of messy for-loops if I can avoid it; I definitely believe I've overcomplicated this problem massively.
We can neaten your code quite a bit.
Take some example data:
files = {'abc4.dat';'abc5.dat';'def4.dat';'ghi4.dat';'abc6.dat';'def5.dat';'nonum.dat'};
You can get the final numbers using regexp and matching one or more digits followed by '.dat', then using strrep to remove the '.dat'.
filenums = cellfun(#(r) strrep(regexp(r, '\d+.dat', 'match', 'once'), '.dat', ''), ...
files, 'uniformoutput', false);
Now we can put these in a structure, using the unique numbers (prefixed by a letter because fields can't start with numbers) as field names.
% Get unique file numbers and set up the output struct
ufilenums = unique(filenums);
filestruct = struct;
% Loop over file numbers
for ii = 1:numel(ufilenums)
% Get files which have this number
idx = cellfun(#(r) strcmp(r, ufilenums{ii}), filenums);
% Assign the identified files to their struct field
filestruct.(['x' ufilenums{ii}]) = files(idx);
end
Now you have a neat output
% Files with numbers before .dat given a field in the output struct
filestruct.x4 = {'abc4.dat' 'def4.dat' 'ghi4.dat'}
filestruct.x5 = {'abc5.dat' 'def5.dat'}
filestruct.x6 = {'abc6.dat'}
% Files without numbers before .dat also captured
filestruct.x = {'nonum.dat'}

Saving figure without providing filename [duplicate]

this question about matlab:
i'm running a loop and each iteration a new set of data is produced, and I want it to be saved in a new file each time. I also overwrite old files by changing the name. Looks like this:
name_each_iter = strrep(some_source,'.string.mat','string_new.(j).mat')
and what I#m struggling here is the iteration so that I obtain files:
...string_new.1.mat
...string_new.2.mat
etc.
I was trying with various combination of () [] {} as well as 'string_new.'j'.mat' (which gave syntax error)
How can it be done?
Strings are just vectors of characters. So if you want to iteratively create filenames here's an example of how you would do it:
for j = 1:10,
filename = ['string_new.' num2str(j) '.mat'];
disp(filename)
end
The above code will create the following output:
string_new.1.mat
string_new.2.mat
string_new.3.mat
string_new.4.mat
string_new.5.mat
string_new.6.mat
string_new.7.mat
string_new.8.mat
string_new.9.mat
string_new.10.mat
You could also generate all file names in advance using NUM2STR:
>> filenames = cellstr(num2str((1:10)','string_new.%02d.mat'))
filenames =
'string_new.01.mat'
'string_new.02.mat'
'string_new.03.mat'
'string_new.04.mat'
'string_new.05.mat'
'string_new.06.mat'
'string_new.07.mat'
'string_new.08.mat'
'string_new.09.mat'
'string_new.10.mat'
Now access the cell array contents as filenames{i} in each iteration
sprintf is very useful for this:
for ii=5:12
filename = sprintf('data_%02d.mat',ii)
end
this assigns the following strings to filename:
data_05.mat
data_06.mat
data_07.mat
data_08.mat
data_09.mat
data_10.mat
data_11.mat
data_12.mat
notice the zero padding. sprintf in general is useful if you want parameterized formatted strings.
For creating a name based of an already existing file, you can use regexp to detect the '_new.(number).mat' and change the string depending on what regexp finds:
original_filename = 'data.string.mat';
im = regexp(original_filename,'_new.\d+.mat')
if isempty(im) % original file, no _new.(j) detected
newname = [original_filename(1:end-4) '_new.1.mat'];
else
num = str2double(original_filename(im(end)+5:end-4));
newname = sprintf('%s_new.%d.mat',original_filename(1:im(end)-1),num+1);
end
This does exactly that, and produces:
data.string_new.1.mat
data.string_new.2.mat
data.string_new.3.mat
...
data.string_new.9.mat
data.string_new.10.mat
data.string_new.11.mat
when iterating the above function, starting with 'data.string.mat'

Matlab | How to load/use files with consecutive names (abc1, abc2, abc3) and then pass on to the next series (cba1, cba2, cba3)?

I have a folder containing a series of data with file names like this:
abc1
abc2
abc3
bca1
bca2
bca3
bca4
bca5
cba1
... etc
My goal is to load all the relevant files for each file name, so all the "abc" files, and plot them in one graph. Then move on to the next file name, and do the same, and so forth. Is there a way to do this?
This is what I currently have to load and run through all the files, grab the data in them and get their name (without the .mat extension) to be able to save the graph with the same filename.
dirName = 'C:\DataDirectory';
files = dir( fullfile(dirName,'*.mat') );
files = {files.name}';
data = cell(numel(files),1);
for i=1:numel(files)
fname = fullfile(dirName,files{i});
disp(fname);
files{i} = files{i}(1:length(files{i})-4);
disp(files{i});
[Rest of script]
end
You already found out about the cool features of dir, and have a cell array files, which contains all file names, e.g.
files =
'37abc1.mat'
'37abc2.mat'
'50bca1.mat'
'50bca2.mat'
'1cba1.mat'
'1cba2.mat'
The main task now is to find all prefixes, 37abc, 50bca, 1cba, ... which are present in files. This can be done using a regular expression (regexp). The Regexp Pattern can look like this:
'([\d]*[\D]*)[\d]*.mat'
i.e. take any number of numbers ([\d]*), then any number of non-numeric characters ([\D]*) and keep those (by putting that in brackets). Next, there will be any number of numeric characters ([\d]*), followed by the text .mat.
We call the regexp function with that pattern:
pre = regexp(files,'([\d]*[\D]*)[\d]*.mat','tokens');
resulting in a cell array (one cell for each entry in files), where each cell contains another cell array with the prefix of that file. To convert this to a simple not-nested cell array, we call
pre = [pre{:}];
pre = [pre{:}];
resulting in
pre =
'37abc' '37abc' '50bca' '50bca' '1cba' '1cba'
To remove duplicate entries, we use the unique function:
pre = unique(pre);
pre =
'37abc' '50bca' '1cba'
which leaves us with all prefixes, that are present. Now you can loop through each of these prefixes and apply your stuff. Everything put together is:
% Find all files
dirName = 'C:\DataDirectory';
files = dir( fullfile(dirName,'*.mat') );
files = {files.name}';
% Find unique prefixes
pre = regexp(files,'([\d]*[\D]*)[\d]*.mat','tokens');
pre = [pre{:}]; pre = [pre{:}];
pre = unique(pre);
% Loop through prefixes
for ii=1:numel(pre)
% Get files with this prefix
curFiles = dir(fullfile(dirName,[pre{ii},'*.mat']));
curFiles = {curFiles.name}';
% Loop through all files with this prefix
for jj=1:numel(curFiles)
% Here the magic happens
end
end
Sorry, I misunderstood your question, I found this solution:
file = dir('*.mat')
matching = regexp({file.name}, '^[a-zA-Z_]+[0-9]+\.mat$', 'match', 'once'); %// Match once on file name, must be a series of A-Z a-z chars followed by numbers.
matching = matching(~cellfun('isempty', matching));
str = unique(regexp(matching, '^[a-zA-Z_]*', 'match', 'once'));
str = str(~cellfun('isempty', str));
group = cell(size(str));
for is = 1:length(str)
ismatch = strncmp(str{is}, matching, length(str{is}));
group{is} = matching(ismatch);
end
Answer came from this source: Matlab Central

Extract variables from a textfile in matlab

I have a large text file (~3500 lines) which contains output data from an instrument. This consists of repeated entries from different measurements which are all formatted as follows:
* LogFrame Start *
variablename1: value
variablename2: value
...
variablename35: value
* LogFrame End *
Each logframe contains 35 variables. From these I would like to extract two, 'VName' and 'EMGMARKER' and put the associated values in columns in a matlab array, (i.e. the array should be (VName,EMGMARKER) which I can then associate with data from another output file which I already have in a matlab array. I have no idea where to start with this in order to extract the variables from this file, so hence my searches on the internet so far have been unsuccessful. Any advice on this would be much appreciated.
You could use textscan:
C = textscan(file_id,'%s %f');
Then you extract the variables of interest like this:
VName_indices = strcmp(C{1},'VName:');
VName = C{2}(VName_indices);
If the variable names, so 'VName' and 'EMGMARKER' , are always the same you can just read through the file and search for lines containing them and extract data from there. I don't know what values they contain so you might have to use cells instead of arrays when extracting them.
fileID = fopen([target_path fname]); % open .txt file
% read the first line of the specified .txt file
current_line = fgetl(fileID);
counter = 1;
% go through the whole file
while(ischar(current_line))
if ~isempty(strfind(current_line, VName))
% now you find the location of the white space delimiter between name and value
d_loc = strfind(current_line,char(9));% if it's tab separated - so \t
d_loc = strfind(current_line,' ');% if it's a simple white space
variable_name{counter} = strtok(current_line);% strtok returns everything up until the first white space
variable_value{counter} = str2double(strtok(current_line(d_loc(1):end)));% returns everything form first to second white space and converts it into a double
end
% same block for EMGMARKER
counter = counter+1;
current_line = fgetl(fileID);% next line
end
You do the same for EMGMARKER and you have cells containing the data you need.