# Handling data cell array

36 views (last 30 days)
Francisco Pinto on 30 Jan 2021
Commented: Francisco Pinto on 30 Jan 2021
Hi there,
I am working with a cell array (numbers and strings) and need to reorganise my data. The problem is I struggle to rearrrange the data from my cell array.
This is an example of what I have:
A = {'x 30%/y 20%' 'x 10%' 'x 50%/z 40%' 'z 15%' 'y 5%/z 90%' 'z 25%'}';
I would like to rearrange the data from the array A in three columns, corresponding to x, y and z where each row correponds to the number accompanying each string value (x,y, and z) and zero in case there is no explicit string value. Specifically, I would like to have something like this:
B = [30 20 0; 10 0 0; 50 0 40; 0 0 15; 0 5 90;0 0 25];
Thanks a lot in advance for any help/hint.
Best wishes,
Fco.
Ps: I'm using Matlab R2019b

the cyclist on 30 Jan 2021
It's not pretty, but it does what you want:
% Original data
A = {'x 30%/y 20%' 'x 10%' 'x 50%/z 40%' 'z 15%' 'y 5%/z 90%' 'z 25%'}';
% Row count
rows = size(A,1);
% Identify the rows with x,y,z
idx = [contains(A,{'x'}) contains(A,{'y'}) contains(A,{'z'})];
% Extract the numeric values.
% "regexp" extracts strings, then "strdouble" converts to numeric
values = cellfun(@(x)(str2double(regexp(x,'\d*','match'))),A,'UniformOutput',false);
% Initialize new array
B = zeros(rows,3);
% Row-by-row, insert values into corresponding index locations
for nr = 1:rows
B(nr,idx(nr,:)) = values{nr};
end
Note that this algorithm relies on the fact that the x,y,z values appear in that order, and you never have a row like
A = {'z 30%/y 20%'}
Francisco Pinto on 30 Jan 2021
Dear Cyclist, thanks a lot! I does what I need. Luckily in my case the order is always like this: x,y,z.

Paul Hoffrichter on 30 Jan 2021
Edited: Paul Hoffrichter on 30 Jan 2021
Yes, regex is elegant. Here is a non-regex script.
This algorithm allows the x,y,z to be in any order in each row of A.
A = {'x 30%/y 20%' 'x 10%' 'x 50%/z 40%' 'z 15%' 'y 5%/z 90%' 'z 25%'}'
Alen = length(A);
B = zeros(Alen,3);
letters = {'x', 'y', 'z'};
for row = 1:Alen
entry = A{row};
col = 1;
for ch = letters
lOffset = strfind( entry, ch );
if ~isempty( lOffset )
pOffset = find( entry(lOffset+1:end) == '%', 1, 'first' );
B(row,col) = str2double(entry( lOffset+1: lOffset+1+pOffset-2 ));
end
col = col + 1;
end
end
B
Output:
A =
6×1 cell array
{'x 30%/y 20%'}
{'x 10%' }
{'x 50%/z 40%'}
{'z 15%' }
{'y 5%/z 90%' }
{'z 25%' }
B =
30 20 0
10 0 0
50 0 40
0 0 15
0 5 90
0 0 25
Francisco Pinto on 30 Jan 2021
Dear Paul, it works perfectly. Thanks a lot!