Reformatting a cell array based on the duplicates

19 visualizzazioni (ultimi 30 giorni)
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 Commenti
the cyclist
the cyclist il 6 Feb 2017
Just to clarify ...
Are these values stored in data type table, or data type cell array?
Johnny
Johnny il 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).

Accedi per commentare.

Risposta accettata

the cyclist
the cyclist il 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.

Più risposte (1)

Stephen23
Stephen23 il 6 Feb 2017
Modificato: Stephen23 il 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 Commento
Johnny
Johnny il 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,

Accedi per commentare.

Categorie

Scopri di più su Downloads in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by