1
votes

Going nuts with cell array, because I just can't get rid of it... However, it will be an easy one for you guys out here.

So here is why: I have a dataset (data) which contains two variables: A (Numbers) and B (cell array). Unfortunately I can't even reconstruct the problem nevertheless my imported table looks like this:

data=dataset;
data.A = [1;1;3;3;3];
data.B = ['A';'A';'BUU';'BUU';'A'];

where data.B is of the type 5x1 cell which I can't reconstruct

all I want now is the unique rows like

ans= [1 A;3 BUU;3 A] the result should be in a dataset or just two vectors where the rows are equivalent.

but unique([dataA dataB],'rows') can't handle cell arrays and I can't find anywhere in the www how I simple convert the cell array B to a vector of strings (does it exist?).

cell2mat() didn't work for me, because of the different word length ('A' vs 'BUU').

Though, two things I would love to learn: Making an 5x1 cell to an string vector and find unique rows out of numbers and strings (or cells).

Thank you very much!

Cheers Dominik

2
You say data.B is a 5x1 cell array, So the line that defines data.B should have {} instead of [], right?Luis Mendo

2 Answers

1
votes

The problem is that the A and B fields are of a different type. Although they could be concatenated into a cell array, unique can't handle that. A general trick for cases like this is to "translate" elements of each field (column) to unique identifiers, i.e. numbers. This translation can be done applying unique to each field separately and getting its third output. The obtained identifiers can now be concatenated into a matrix, so that each row of this matrix is a "composite identifier". Finally, unique with 'rows' option can be applied to this matrix.

So, in your case:

[~, ~, kA] = unique(data.A);
[~, ~, kB] = unique(data.B);
[~, jR] = unique([kA kB], 'rows');

Now build the result as (same format as data)

result.A = data.A(jR);
result.B = data.B(jR);

or as (2D cell array)

result = cat(2, mat2cell(data.A(jR), ones(1,numel(jR))), data.B(jR));
0
votes

Here is my clumpsy solution

    tt.A = [1;1;3;3;3];
    tt.B = {'A';'A';'BUU';'BUU';'A'};

Convert integers to characters, then merge and find unique strings

   tt.C = cellstr(num2str(tt.A));
   tt.D = cellfun(@(x,y) [x y],tt.C,tt.B,'UniformOutput',0);
   [tt.F,tt.E] = unique(tt.D);

Display results

   tt.F