Matlab: Remove fields with similar string names in a single command - string

So I have a structure, r, that contains multiple headers of the form:
Header_0001
Header_0002
Header_0003, and so on whose names are represented as strings.
Is there a way to format the strings so that I can remove these headers with a single command?
i.e.
r=rmfield(r,Header_00XX)
where X can be any number. I have tried using wildcards, anchors, etc. but have not found a method that works as of yet.

Try this:
fields = fieldnames(r);
r = rmfield(r, fields(find(~cellfun(#isempty,strfind(fields, 'Header_00')))))

Related

How can I use a specified order of strings to index from a cell array?

I am trying to index from a cell aray of a number of potential reference files to use for a comparison. The comparison files have distinct parts of their file names that I'd like to use to specify a single reference file.
However, I'm only able to return reference files that contain the three distinct parts, in any order. How can I enforce the order?
Example:
The comparison file is:
deg_baseFileName = "Test1_female_44k_70dBA_babble7ch_1sp_20k_00dBA_48k"
I use strsplit to break the filename into parts:
deg_parts = strsplit(deg_baseFileName, "_");
The distinguishing parts are:
deg_parts(2), deg_parts(4), deg_parts(8)
In this case: "female", "70dBA", "00dBA" - in that order.
I use these functions to identify and index with the distinguishing parts:
strToFind = {string(deg_parts(2)),string(deg_parts(4)),string(deg_parts(8))}'; % Strings to match
fun = #(s)~cellfun('isempty',strfind(ref_files,s));
out = cellfun(fun,strToFind,'UniformOutput',false);
idx = all(horzcat(out{:}),2);
However, the index returns two values from my reference file cell array:
Ref_female_44k_00dBA_babble7ch_1sp_20k_70dBA_48k.wav
Ref_female_44k_70dBA_babble7ch_1sp_20k_00dBA_48k.wav
Both contain the distinguishing parts, but only the second in the correct order.
Is there a way I can enforce the order in my out call?
Thanks!
In the simplest case, where the comparison and reference files only differ in their first part, you can use strrep:
refFile = strrep(deg_baseFileName, 'Test1', 'Ref');
If you know what the other parts of the file name will be, and they are the same for all the reference files but differ from the comparison file, you can just use sprintf to create your file name:
refFile = sprintf('Ref_%s_44k_%s_babble7ch_1sp_20k_%s_48k.wav', ...
deg_parts(2), deg_parts(4), deg_parts(8));
If you don't know or care what the other parts could be, you can generalize the above to create a match expression for use with regexp to find the index of reference files with the correct order:
expr = sprintf('Ref_%s_[^_]+_%s_[^_]+_[^_]+_[^_]+_%s_[^_]+.wav', ...
deg_parts(2), deg_parts(4), deg_parts(8));
index = ~cellfun('isempty', regexp(ref_files, expr));

splitting directory fileparts into sections using matlab / octave

I would like to split pathstr into separate parts how can I do this? See example below.
PS: I'm using octave 3.8.1
dpath='tmp/h1/cli/pls/03sox_a_Fs_1000/'
[pathstr,name,ext] = fileparts(dpath)
>>>pathstr = tmp/h1/cli/pls/03sox_a_Fs_1000
If all I want is 03sox_a_Fs_1000 or pls
How can I do this?
Please note the filenames will change and could be of different lengths.
You can use strsplit (here using Matlab) to split your string (believe it or not!) using the delimiter /:
pathstr = 'tmp/h1/cli/pls/03sox_a_Fs_1000'
[Name,~] = strsplit(pathstr,'/')
Now Name looks like this:
Name =
'tmp' 'h1' 'cli' 'pls' '03sox_a_Fs_1000'
So you can select the last element using the end keyword and curly braces since the output of strsplit is a cell array:
Name = Name{end}
or end-1 to retrieve pls.
This applies to names of any length or format, as long as they are separated by /.

xlsread ('not the file name but a string contained in an element of an array that is the file name)

I would like to read an excel file (xlsread) but I don't want to put manually the string every time but instead I want to xlsread the name of the file that is contained in an array.
For example, my array B is:
B =
'john.xlsx'
'mais.xlsx'
'car.xlsx'
Then I would like to read the excel WITH THE NAME that is inside the first element, that means: "john.xlsx"
How can I do this?
data = xlsread(B{1});
Or, if you want to read all of them:
for i=1:length(B)
data(i).nums = xlsread(B{i});
end
Assuming, of course, your B is a cell array. If it's not, it can't exist the way you described it. If all strings have the same length (then it would be possible) or padding with spaces, you can split the char array into a cell array using
B = mat2cell(B,ones(size(B,1),1),size(B,2));
Strings of different lengths would have to be inside a cell array, which you can access elements via the curly brackets {}. So, you can call xlsread on the first element this way:
names{1} = 'john.xlsx';
names{2} = 'mais.xlsx';
names{3} = 'car.xlsx';
num = xlsread(names{1});

Using load with data from cells

In my code I'm trying to use load with entries from a cell, but it is not working. The portion of my code below produces a 3 dimensional array of strings. The strings represent the paths to file names.
for i = 1:Something
for j = 1:Something Different
for k = 1: Yet Something Something Different
DataPath{j,k,i} = 'F:\blah\blah\blah\fileijk %file changes based on i,j,and k
end
end
end
In the next part of the code I want to use load to open the files using the path names defined in the code above. I do this using the code below.
Dummy = DataPath{l,(k-1)*TSRRange+m};
Data = load(Dummy);
The idea is for Dummy to take the string content out of DataPath so I can use it in load. By doing this I thought that Dummy would be defined as a string and not a cell, but this is not the case. How do I pull the string out of DataPath so I can use it with load? Thanks.
I have to load the data this way because the data is located in multiple folders. I can post more of the code if needed, but it is complex.
Dummy is a cell because you assigned a 3D cell array but are accessing a 2D cell with Dummy = Datapath{1,(k-1)*TSRRange+m}
I don't believe that you can expect to access all cell elements I this way. Instead, use three indices just as you did when creating it.

How to store string matrix and write to a file?

I don't know if Matlab can do this, but I want to store some strings in a 4×3 matrix, each element in the matrix is a string.
test_string_01 test_string_02 test_string_03
test_string_04 test_string_05 test_string_06
test_string_07 test_string_08 test_string_09
test_string_10 test_string_11 test_string_12
Then, I want to write this matrix into a plain text file, either comma or space delimited.
test_string_01,test_string_02,test_string_03
test_string_04,test_string_05,test_string_06
test_string_07,test_string_08,test_string_09
test_string_10,test_string_11,test_string_12
Seems like matrix data type is not capable of storing strings. I looked at cell. I tried to use dlmwrite() or csvwrite(), but both of them only accept matrices. I also tried cell2mat() first, but in that way all letters in the strings are comma seperated, like
t,e,s,t,_,s,t,r,i,n,g,_,0,1,t,e,s,t,_,s,t,r,i,n,g,_,0,2,t,e,s,t,_,s,t,r,i,n,g,_,0,3
So is there any way to achieve this?
It is possible to shorten yuk's solution a bit.
strings = {
'test_string_01','test_string_02','test_string_03'
'test_string_04','test_string_05','test_string_06'
'test_string_07','test_string_08','test_string_09'
'test_string_10','test_string_11','test_string_12'};
fid = fopen('output.txt','w');
fmtString = [repmat('%s\t',1,size(strings,2)-1),'%s\n'];
fprintf(fid,fmtString,strings{:});
fclose(fid);
Cell array is the way to store strings.
I agree it's a pain to save strings into a text file, but you can do it with this code:
strings = {
'test_string_01','test_string_02','test_string_03'
'test_string_04','test_string_05','test_string_06'
'test_string_07','test_string_08','test_string_09'
'test_string_10','test_string_11','test_string_12'};
fid = fopen('output.txt','w');
for row = 1:size(strings,1)
fprintf(fid, repmat('%s\t',1,size(strings,2)-1), strings{row,1:end-1});
fprintf(fid, '%s\n', strings{row,end});
end
fclose(fid);
Substitute \t with , to get csv file.
You can also store cell array of strings into Excel file with XLSWRITE (requires COM interface, so it's on Windows only):
xlswrite('output.xls',strings)
In most cases you can use the delimiter ' ' and get Matlab to save a string into file with dlmwrite.
For example,
output=('my_first_String');
dlmwrite('myfile.txt',output,'delimiter','')
will save a file named myfile.txt containing my_first_String.

Resources