這是一個試圖完成這項工作的功能。您提供兩個表格,一個用於決定是否合併兩行的閾值以及一個邏輯,用於說明在合併衝突出現時您是否希望從第一個表格獲取值。我沒有爲極端情況下準備,但看到它可以讓你用:
TkeepAll=mergeTables(Tb,Ta,1,true)
TmergeSome=mergeTables(Tb,Ta,0.25,true)
TmergeAll=mergeTables(Tb,Ta,-1,true)
這裏是功能:
function Tmerged=mergeTables(Ta,Tb,threshold,preferA)
%% parameters
% Ta and Tb are two the two tables to merge
% threshold=0.25; minimal ratio of identical values in rows for merge.
% example: you have one row in table A with 3 values, but you only have two
% values for the same columns in data B. if one of the values is identical
% and one isn't, you have ratio of 1/2 aka 0.5, which passes a threshold of
% 0.25
% preferA=true; which to take when there is merge conflict
%% see how well rows fit to each other
% T1 is the table with fewer rows
if size(Ta,1)<=size(Tb,1)
T1=Ta;
T2=Tb;
prefer1=preferA;
else
T1=Tb;
T2=Ta;
prefer1=~preferA;
end
[commonVar1,commonVar2]=ismember(T1.Properties.VariableNames,...
T2.Properties.VariableNames);
commonVar1=find(commonVar1);
commonVar2(commonVar2==0)=[];
% fit is a table with the size of N rows T1 by M rows T2, with values
% describing what ratio of identical items between each row in
% table 1 (shorter) and each row in table 2 (longer), among all not-missing
% points
for ii=1:size(T1,1) %rows of T1
for jj=1:size(T2,1)
fit(ii,jj)=sum(ismember(T1{ii,commonVar1},T2{jj,commonVar2}))/length(commonVar1);
end
end
%% pair rows according to fit
% match has two columns, first one has T1 row number and secone one has the
% matching T2 row number
unpaired1=true(size(T1,1),1);
unpaired2=true(size(T2,1),1);
count=0;
match=[];
maxv=max(fit,[],2);
[~,order]=sort(maxv,'descend');
order=order';
for ii=order %1:size(T1,1)
[maxv,maxi]=max(fit,[],2);
if maxv(ii)>threshold
count=count+1;
match(count,1)=ii;
match(count,2)=maxi(ii);
unpaired1(ii)=false;
unpaired2(match(count,2))=false;
fit(:,match(count,2))=nan; %exclude paired row from next pairing
end
end
%% prepare new variables
% first variables common to the two tables
Nrows=sum(unpaired1)+sum(unpaired2)+size(match,1);
namesCommon={};
namesCommon(1:length(commonVar1))={T1.Properties.VariableNames{commonVar1}};
for vari=1:length(commonVar1)
if isempty(match)
mergedData={};
else
if prefer1
mergedData=T1{match(:,1),commonVar1(vari)}; %#ok<*NASGU>
else
mergedData=T2{match(:,2),commonVar2(vari)};
end
end
data1=T1{unpaired1,commonVar1(vari)};
data2=T2{unpaired2,commonVar2(vari)};
eval([namesCommon{vari},'=[data1;mergedData;data2];']);
end
% variables only in 1
uncommonVar1=1:size(T1,2);
uncommonVar1(commonVar1)=[];
names1={};
names1(1:length(uncommonVar1))={T1.Properties.VariableNames{uncommonVar1}};
for vari=1:length(uncommonVar1)
data1=T1{:,uncommonVar1(vari)};
tmp=repmat({''},Nrows-size(data1,1),1);
eval([names1{vari},'=[data1;tmp];']);
end
% variables only in 2
uncommonVar2=1:size(T2,2);
uncommonVar2(commonVar2)=[];
names2={};
names2(1:length(uncommonVar2))={T2.Properties.VariableNames{uncommonVar2}};
for vari=1:length(uncommonVar2)
data2=T2{:,uncommonVar2(vari)};
tmp=repmat({''},Nrows-size(data2,1),1);
eval([names2{vari},'=[tmp;data2];']);
end
%% collect variables to a table
names=sort([namesCommon,names1,names2]);
str='table(';
for vari=1:length(names)
str=[str,names{vari},','];
end
str=[str(1:end-1),');'];
Tmerged=eval(str);
這是非常相似的[前一個問題(https://開頭計算器。 com/questions/46682751 /有效的方法來追加新的數據在matlab與示例代碼)對嗎? – Wolfie
不是真的,因爲我真的打算如何使用Matlab Table將兩個表連接在一起。它與上一個問題不同,我區分行和列,以及我處理數字數據的位置 - 如果您可以向我展示與上一個問題的聯繫,那將很棒。 – JohnAndrews
還要注意,在這個問題中,沒有唯一的行。它只是行數不同而已。 – JohnAndrews