Handling data cell array

3 views (last 30 days)
Francisco Pinto
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

Accepted Answer

the cyclist
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%'}
  1 Comment
Francisco Pinto
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.

Sign in to comment.

More Answers (1)

Paul Hoffrichter
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
  1 Comment
Francisco Pinto
Francisco Pinto on 30 Jan 2021
Dear Paul, it works perfectly. Thanks a lot!

Sign in to comment.

Categories

Find more on Structures in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!