converting integer chars to numeric array in matlab - 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))

Related

Converting cell array of string arrays to a double array

I have a 55X1 cell array. Each cell contains a 1X178 string array of numbers. I would like to convert all the cells to a double array, but in such a way that it forms a 55X178 double array.
Take, for example, the 55X1 cell array dataCellOut = {each cell has a 1X178 string}. I can use: na=str2num(dataCellOut{1}) and this will output a 1X178 double array. I have tried using: na=cellfun(#str2num, dataCellOut, 'UniformOutput', false) and this does not work (error: "input must be a character vector or string scalar"). I have worked on this for awhile to no avail.
I hope this makes sense and if there is anything else that I can offer please don't hesitate to let me know. Thank you in advance!
According to the documentation to str2num:
The str2num function does not convert cell arrays or nonscalar string arrays, and is sensitive to spacing around + and - operators. In addition, str2num uses the eval function, which can cause unintended side effects when the input includes a function name. To avoid these issues, use str2double.
str2double, however, does just as you want:
X = str2double(str) converts the text in str to double precision values. [...] str can be a character vector, a cell array of character vectors, or a string array. [...] If str is [...] a string array, then X is a numeric array that is the same size as str.
Thus, this should work:
na = cellfun(#str2double, dataCellOut, 'UniformOutput', false);
na = cat(1,na{:});
This simple statement works for me.
str2num(char(cellstr_array))

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{:}]);

Using fscanf in MATLAB to read an unknown number of columns

I want to use fscanf for reading a text file containing 4 rows with an unknown number of columns. The newline is represented by two consecutive spaces.
It was suggested that I pass : as the sizeA parameter but it doesn't work.
How can I read in my data?
update: The file format is
String1 String2 String3
10 20 30
a b c
1 2 3
I have to fill 4 arrays, one for each row.
See if this will work for your application.
fid1=fopen('test.txt');
i=1;
check=0;
while check~=1
str=fscanf(fid1,'%s',1);
if strcmp(str,'')~=1;
string(i)={str};
end
i=i+1;
check=strcmp(str,'');
end
fclose(fid1);
X=reshape(string,[],4);
ar1=X(:,1)
ar2=X(:,2)
ar3=X(:,3)
ar4=X(:,4)
Once you have 'ar1','ar2','ar3','ar4' you can parse them however you want.
I have found a solution, i don't know if it is the only one but it works fine:
A=fscanf(fid,'%[^\n] *\n')
B=sscanf(A,'%c ')
Z=fscanf(fid,'%[^\n] *\n')
C=sscanf(Z,'%d')
....
You could use
rawText = getl(fid);
lines = regexp(thisLine,' ','split);
tokens = {};
for ix = 1:numel(lines)
tokens{end+1} = regexp(lines{ix},' ','split'};
end
This will give you a cell array of strings having the row and column shape or your original data.
To read an arbitrary line of text then break it up according the the formating information you have available. My example uses a single space character.
This uses regular expressions to define the separator. Regular expressions powerful but too complex to describe here. See the MATLAB help for regexp and regular expressions.

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

why strcat() doesn't return a string in 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})