Reformatting a cell array based on the duplicates

26 vues (au cours des 30 derniers jours)
Johnny
Johnny le 6 Fév 2017
Commenté : Johnny le 6 Fév 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 commentaires
the cyclist
the cyclist le 6 Fév 2017
Just to clarify ...
Are these values stored in data type table, or data type cell array?
Johnny
Johnny le 6 Fév 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).

Connectez-vous pour commenter.

Réponse acceptée

the cyclist
the cyclist le 6 Fév 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.
  1 commentaire
Johnny
Johnny le 6 Fév 2017
Thank you this works fine for me. Kind regards

Connectez-vous pour commenter.

Plus de réponses (1)

Stephen23
Stephen23 le 6 Fév 2017
Modifié(e) : Stephen23 le 6 Fév 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 commentaire
Johnny
Johnny le 6 Fév 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,

Connectez-vous pour commenter.

Catégories

En savoir plus sur Downloads dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by