I have three matrices that have common calendar. A part of these matrices is as follows:

A=[2000 1 2 230 240; 2000 1 3 240 250; 2000 1 5 260 270];

B=[2000 1 4 240 260; 2000 1 2 270 300; 2000 1 5 200 210];

C=[2000 1 5 240 260; 2000 1 7 270 300; 2000 1 2 200 210];

I want to extract the common calendar. For example, in the example above, the result is as follows:

D=[2000 1 2 230 240 2000 1 2 270 300 2000 1 2 200 210;

2000 1 5 260 270 2000 1 5 200 210 2000 1 5 240 260];

Thanks,

Answer by dpb
on 1 May 2019

Edited by dpb
on 1 May 2019

Accepted Answer

ABC=[A;B;C];

d=datetime(ABC(:,1:3));

g=findgroups(d);

D=splitapply(@(x) {vertcat(x)},ABC,g);

D=cell2mat(D(cellfun(@(c)size(c,1),D)>1));

D=reshape(D.',max(histc(g,unique(g)))*size(ABC,2),[]).'

The last presumes the number of matching dates is the same in all groups to be able to reshape to a rectangular array; the previous array will be the groups with more than one element in an column-oriented array; that step without cell2mat will leave a cell array with the duplicated dates in separate cells that could have differering numbers but still with at least two elements per cell.

HN
on 1 May 2019

Thank you for answering. But this script does not run for the original data.

My main data is

A=3456*5

B=2967*5

C=2818*5

I encounter with the following error:

Error using reshape

Product of known dimensions, 30, not divisible into total number of elements, 43840.

Error in code (line 7)

D=reshape(D.',max(histc(g,unique(g)))*size(ABC,2),[]).';

dpb
on 1 May 2019

I pointed out you've got issues in general with trying to reshape stuff...unless the data fit the very specific condition that there are the identical number of elements of each date, you're not going to have a rectangular array possible, in general.

What was the result of the previous step prior to trying to reshape? In particular, it would be most simple to look at the result also before the cell2mat so can see what the sizes of the various cell arrays are.

dpb
on 1 May 2019

Had a couple minutes, so...

D=splitapply(@(x) {vertcat(x)},ABC,g);

>> D(1:10)

ans =

10×1 cell array

{2×5 double}

{3×5 double}

{3×5 double}

{3×5 double}

{3×5 double}

{1×5 double}

{3×5 double}

{3×5 double}

{3×5 double}

{3×5 double}

>>

and you see the problem right off the bat -- there are two dates that match first, then three for several cases, then only one (that will get thrown out next step), but you can't reshape five elements into a 3*N X 5 array. Just can't be done.

Your expectations are simply unrealistic given the output format arrangement as you showed it with all the matching elements on a row when there aren't identically the same number of matches for every date.

>> D=cell2mat(D(cellfun(@(c)size(c,1),D)>1));

>> D(1:10,:)

ans =

2007 1 1 2 12

2007 1 1 1 1

2007 1 2 1 2

2007 1 2 3 12

2007 1 2 5 123

2007 1 3 1 2

2007 1 3 3 2

2007 1 3 5 123

2007 1 4 5 12

2007 1 4 3 123

>>

also illustrates the logic of grouping worked just fine; there are two entries for 1/1/2007 and three for 1/2/2007, both of which are > only one match.

As I suggested initially, for such a dataset, I'd guess it's highly likely the cell array form is the most useful but you'll have to decide just what it is you're really after.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.