why strcat() doesn't return a string in Matlab? - matlab

I'm trying to access multiple files in a for loop, like this:
age = xlsread(strcat('Pipeline_BO_2013_',names(2),'_CDBU.xlsx'), 'Data', 'H:I')
It returns an error the filename must be string. So I did following test:
filename = strcat('Pipeline_BO_2013_',names(2),'_CDBU.xlsx')
filename =
'Pipeline_BO_2013_0107_CDBU.xlsx'
isstr(filename)
ans =
0
This is so weird. Could any one help me out? Thank you so much.

It looks like names is a cellstr and not a char array. If so, indexing in to it with parentheses like names(2) will return a 1-long cellstr array, not a char array. And when strcat is called with any of its arguments as a cellstr, it returns a cellstr. Then xlsread errors because it wants a char, not a cellstr.
Instead of just calling isstr or ischar on filename, do class(filename) and it'll tell you what it is.
Another clue is that filename is displayed with quotes. This is how cellstrs are displayed. If it were a char array, it would be displayed without quotes.
If this is the case, and names is a cellstr, you need to use {} indexing to "pop out" the cell contents.
filename = strcat('Pipeline_BO_2013_',names{2},'_CDBU.xlsx')
Or you can use sprintf, which you may find more readable, and will be more flexible once you start interpolating multiple arguments of different types.
filename = sprintf('Pipeline_BO_2013_%s_CDBU.xlsx', names{2})
% An example of more flexibility:
year = 2013;
filename = sprintf('Pipeline_BO_%04d_%s_CDBU.xlsx', year, names{2})

Related

MATLAB: extract numerical data from alphanumerical table and save as double

I created a list of names of data files, e.g. abc123.xml, abc456.xml, via
list = dir('folder/*.xml').
Matlab starts this out as a 10x1 struct with 5 fields, where the first one is the name. I extracted the needed data with struct2table, so I now got a 10x1 table. I only need the numerical value as 10x1 double. How can I get rid of the alphanumerical stuff and change the data type?
I tried regexp (Undefined function 'regexp' for input arguments of type 'table') and strfind (Conversion to double from table is not possible). Couldn't come up with anything else, as I'm very new to Matlab.
You can extract the name fields and place them in a cell array, use regexp to capture the first string of digits it finds in each name, then use str2double to convert those to numeric values:
strs = regexp({list.name}, '(\d+)', 'once', 'tokens');
nums = str2double([strs{:}]);

converting integer chars to numeric array in matlab

I have a char array of format a = [1.234 ; 2.345; 3.456] and I need to convert this to a numeric array in MATLAB. I have tried str2num(a) but it only seems to work on integers, as it is returning an empty vector. Here is what the data actually looks like:
Any suggestions on how to tackle this problem are appreciated!
If your character array is either of the following formats:
a = '[1.234; 2.345; 3.456]'; % 1-by-N with brackets, spaces, or semicolons
a = ['1.234'; '2.345'; '3.456']; % M-by-N
Then str2num should work as you want:
vec = str2num(a)
vec =
1.234000000000000
2.345000000000000
3.456000000000000
If it's not working then that probably means that your character array val has rows with invalid formats or characters that don't properly convert. Since the array has 3100 rows, you probably don't want to search through it by hand. One easy way to highlight where invalid rows might be is to identify where there are characters other than numbers, periods, or white space. Here's how you can get a list of rows that may warrant further inspection:
suspiciousRows = find(~all(ismember(val, '0123456789. '), 2));
The function str2double would works for your case. Please refer to this link for detailed usage.
str2num would work as it is but as str2num uses eval,so a better alternative is str2double. But it is not directly applicable on a char array like yours. You can convert that array into a cell using cellstr and then apply str2double.
req = str2double(cellstr(val))
Another approach if you have MATLAB R2016b or a later version is to convert that char array into a string array and then apply str2double.
req = str2double(string(val))

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'

Function to split string in matlab and return second number

I have a string and I need two characters to be returned.
I tried with strsplit but the delimiter must be a string and I don't have any delimiters in my string. Instead, I always want to get the second number in my string. The number is always 2 digits.
Example: 001a02.jpg I use the fileparts function to delete the extension of the image (jpg), so I get this string: 001a02
The expected return value is 02
Another example: 001A43a . Return values: 43
Another one: 002A12. Return values: 12
All the filenames are in a matrix 1002x1. Maybe I can use textscan but in the second example, it gives "43a" as a result.
(Just so this question doesn't remain unanswered, here's a possible approach: )
One way to go about this uses splitting with regular expressions (MATLAB's strsplit which you mentioned):
str = '001a02.jpg';
C = strsplit(str,'[a-zA-Z.]','DelimiterType','RegularExpression');
Results in:
C =
'001' '02' ''
In older versions of MATLAB, before strsplit was introduced, similar functionality was achieved using regexp(...,'split').
If you want to learn more about regular expressions (abbreviated as "regex" or "regexp"), there are many online resources (JGI..)
In your case, if you only need to take the 5th and 6th characters from the string you could use:
D = str(5:6);
... and if you want to convert those into numbers you could use:
E = str2double(str(5:6));
If your number is always at a certain position in the string, you can simply index this position.
In the examples you gave, the number is always the 5th and 6th characters in the string.
filename = '002A12';
num = str2num(filename(5:6));
Otherwise, if the formating is more complex, you may want to use a regular expression. There is a similar question matlab - extracting numbers from (odd) string. Modifying the code found there you can do the following
all_num = regexp(filename, '\d+', 'match'); %Find all numbers in the filename
num = str2num(all_num{2}) %Convert second number from str

Loading files in a for loop in matlab

I am trying to load different file names contained in a matlab vector inside a for loop. I wrote the following:
fileNames = ['fileName1.mat', ..., 'fileName_n.mat'];
for i=1:n
load(fileNames(i))
...
end
However, it doesn't work because fileNames(i) returns the first letter of the filename only.
How can I give the full file name as argument to load (the size of the string of the filename can vary)
Use a cell instead of an array.
fileNames = {'fileName1.mat', ..., 'fileName_n.mat'};
Your code is in principle a string cat, giving you just one string (since strings are arrays of characters).
for i=1:n
load(fileNames{i})
...
end
Use { and } instead of parentheses.