Skip to content

Commit

Permalink
FIX #2137 - merge columns with datetime objects, thanks to @JonathanV…
Browse files Browse the repository at this point in the history
  • Loading branch information
robertoostenveld committed Nov 18, 2022
1 parent 5eafb10 commit 45cdfa4
Showing 1 changed file with 40 additions and 27 deletions.
67 changes: 40 additions & 27 deletions private/mergetable.m
Expand Up @@ -46,15 +46,15 @@
if nargin==2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% merge by comparing the complete rows

assert(isequal(t1.Properties.VariableNames, t2.Properties.VariableNames));

[m1, n1] = size(t1);
[m2, n2] = size(t2);

% the unique function fails on tables if the values are mixed, e.g. empty, scalars, and strings
% the following compares every row by computing a hash for it.

h1 = cell(m1,1);
for i=1:m1
h1{i} = ft_hash(t1(i,:));
Expand All @@ -63,10 +63,10 @@
for i=1:m2
h2{i} = ft_hash(t2(i,:));
end

[c, i1, i2] = union(h1, h2, 'stable');
t3 = cat(1, t1(i1,:), t2(i2,:));

% match = true(m2,1);
%
% for j2=1:m2
Expand All @@ -76,20 +76,20 @@
% end
%
% t3 = cat(1, t1, t2(~match,:));

elseif nargin==3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% merge using the specific key

c1 = t1.Properties.VariableNames;
c2 = t2.Properties.VariableNames;

assert(any(contains(c1, key)));
assert(any(contains(c2, key)));

[m1, n1] = size(t1);
[m2, n2] = size(t2);

% don't try to merge if one of them is empty
if m1==0 && m2>0
t3 = t2;
Expand All @@ -98,33 +98,37 @@
t3 = t2;
return
end

for i=1:n1
if ischar(t1{1,i})
t1.(c1{i}) = cellstr(t1{:,i});
elseif isnumeric(t1{1,i})
t1.(c1{i}) = num2cell(t1{:,i});
elseif isdatetime(t1{1,i})
t1.(c1{i}) = datetime2cell(t1{:,i});
end
end

for i=1:n2
if ischar(t2{1,i})
t2.(c2{i}) = cellstr(t2{:,i});
elseif isnumeric(t2{1,i})
t2.(c2{i}) = num2cell(t2{:,i});
elseif isdatetime(t2{1,i})
t2.(c2{i}) = datetime2cell(t2{:,i});
end
end

t3 = table();

% deal with the columns that are present in both inputs
col = intersect(c1, c2);

for i=1:numel(col)
% copy the existing column from t1 into t3
t3.(col{i}) = t1.(col{i});
end

for j=1:m2
row = findkey(t1.(key), t2.(key){j});
if ~any(row)
Expand All @@ -142,47 +146,47 @@
t3(row, col{i}) = t2(j, col{i});
end
end

n3 = size(t3,1);

% deal with the columns that are only present in the 1st input
col = setdiff(c1, c2);

for i=1:numel(col)
% add an empty column to t3
t3.(col{i}) = cell(n3, 1);
end

for j=1:m1
row = findkey(t3.(key), t1.(key){j});
for i=1:numel(col)
t3(row, col{i}) = t1(j, col{i});
end
end

% deal with the columns that are only present in the 2nd input
col = setdiff(c2, c1);

for i=1:numel(col)
% add an empty column to t3
t3.(col{i}) = cell(n3, 1);
end

for j=1:m2
row = findkey(t3.(key), t2.(key){j});
for i=1:numel(col)
t3(row, col{i}) = t2(j, col{i});
end
end

% reorder the columns to match the input
c3 = unique(cat(2, c1, c2), 'stable');
[c3, ia, ib] = intersect(c3, t3.Properties.VariableNames, 'stable');
t3 = t3(:,ib);

else
ft_error('incorrect number of input arguments');

end % if nargin


Expand All @@ -192,3 +196,12 @@
function ret = findkey(list, elem)
match = @(x) isequal(x, elem);
ret = cellfun(match, list);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function c = datetime2cell(d)
c = cell(size(d));
for i=1:numel(d)
c{i} = d(i);
end

0 comments on commit 45cdfa4

Please sign in to comment.