Reformatting a cell array based on the duplicates

20 Ansichten (letzte 30 Tage)
Johnny
Johnny am 6 Feb. 2017
Kommentiert: Johnny am 6 Feb. 2017
Hello, I have a table with two columns and a number of rows (first column contains a variable name and the second column contains its value). The entries of the first column (the variable names) has duplicates, as shown in the example below:
'x1' [1]
'x2' [2]
'x3' [3]
'x4' [4]
'x1' [2]
'x4' [8]
'x2' [5]
'x1' [5]
'x4' [1]
I would like to record the name of the unique variables as the header (without repeatitions) and their values below them. In case of few values, the last value will be repeated just to fill up the cells. From my cell array above I would like to achieve something like this:
'x1' 'x2' 'x3' 'x4'
[ 1] [ 2] [ 3] [ 4]
[ 2] [ 5] [ 3] [ 8]
[ 5] [ 2] [ 3] [ 1]
How would I achieve this? Any Ideas? Kind regards,
  2 Kommentare
the cyclist
the cyclist am 6 Feb. 2017
Just to clarify ...
Are these values stored in data type table, or data type cell array?
Johnny
Johnny am 6 Feb. 2017
For this example, they are stored in a cell array. However, the same logic could be applied to tables. As tables can easily be converted to and from cell arrays (at least to my understanding).

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

the cyclist
the cyclist am 6 Feb. 2017
Here is a straightforward method, if a bit cumbersome. Someone will undoubtedly find a slick one-liner that is better. :-)
A = {
'x1' 1;
'x2' 2;
'x3' 3;
'x4' 4;
'x1' 2;
'x4' 8;
'x2' 5;
'x1' 5;
'x4' 1
}
[uniqueA,~,jj] = unique(A(:,1));
numberUniqueA = numel(uniqueA);
counts = histcounts(jj,[unique(jj); Inf]);
B = cell(max(counts)+1,numberUniqueA);
B(1,:) = uniqueA';
for ni = 1:numberUniqueA
indexToThisA = (ni==jj);
numberThisA = sum(indexToThisA);
B(2:numberThisA+1,ni) = A(indexToThisA,2);
end
This will actually leave empty cell elements, instead of replicating. Is that OK? If not, then it is also easy to just find the empty cells and fill those in.

Weitere Antworten (1)

Stephen23
Stephen23 am 6 Feb. 2017
Bearbeitet: Stephen23 am 6 Feb. 2017
Not quite one line:
>> [U,~,idx] = unique(A(:,1));
>> C = arrayfun(@(n)A(idx==n,2),unique(idx),'Uni',0)';
>> N = max(cellfun('size',C,1));
>> M = cellfun(@(v)[v;repmat(v(end),N-numel(v),1)],C,'Uni',0);
>> Z = [U';[M{:}]]
Z =
'x1' 'x2' 'x3' 'x4'
[ 1] [ 2] [ 3] [ 4]
[ 2] [ 5] [ 3] [ 8]
[ 5] [ 5] [ 3] [ 1]
  1 Kommentar
Johnny
Johnny am 6 Feb. 2017
You are right here, I had made a mistake in my output table in column x2. It should have been like yours here since 5 is duplicated. Sorry for the confusion. Thank you for this CORRECT ANSWER TOO. Regards,

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Downloads finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by