Reformatting a cell array based on the duplicates

21 ビュー (過去 30 日間)
Johnny
Johnny 2017 年 2 月 6 日
コメント済み: Johnny 2017 年 2 月 6 日
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 件のコメント
the cyclist
the cyclist 2017 年 2 月 6 日
Just to clarify ...
Are these values stored in data type table, or data type cell array?
Johnny
Johnny 2017 年 2 月 6 日
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).

サインインしてコメントする。

採用された回答

the cyclist
the cyclist 2017 年 2 月 6 日
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 件のコメント
Johnny
Johnny 2017 年 2 月 6 日
Thank you this works fine for me. Kind regards

サインインしてコメントする。

その他の回答 (1 件)

Stephen23
Stephen23 2017 年 2 月 6 日
編集済み: Stephen23 2017 年 2 月 6 日
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 件のコメント
Johnny
Johnny 2017 年 2 月 6 日
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,

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeDownloads についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by