function Table = outerjoinRowToTable(Table,TableRowToBeAdded) %outerjoinRowToTable Adds one row to a table. Variables that are missing in %either the table or the row are added with empty values {' '} for cells %and NaN for doubles. Works with tables that contain both cells and %doubles. % % * Strings in the table are not yet supported. % * The row that is added needs to be formatted as table % * Update 2024: Adds several rows, that is tables % * Update 2026: Handles peakfitting columns with different size. % % T = outerjoinRowToTable(TableToAddTo,RowToBeAdded) % % tmpTableToBeAdded = table({tmpCombined(:,1)},{tmpCombined(:,2)},{'660eV, m50, 092022'},{'#288,#289,#290.ibw'}, ... % 'VariableNames',["bindingEnergy_eV","spectrum_countsNorm","sample","name"]); % SpectrumList = outerjoinRowToTable(SpectrumList,tmpTableToBeAdded); % % Thorsten, December 2023 % Original Table has more variables if ~all(ismember(Table.Properties.VariableNames,TableRowToBeAdded.Properties.VariableNames)) tmpMissingVariable = ~ismember(Table.Properties.VariableNames,TableRowToBeAdded.Properties.VariableNames); tmpVariablesToBeAdded = Table.Properties.VariableNames(tmpMissingVariable); for ii = 1:size(tmpVariablesToBeAdded,2) if matches(class(Table.(tmpVariablesToBeAdded{ii})),'double') || matches(class(Table.(tmpVariablesToBeAdded{ii})),'int32') tmpContentToBeAdded = NaN(size(TableRowToBeAdded,1),size(Table.(tmpVariablesToBeAdded{ii}),2)); TableRowToBeAdded = addvars(TableRowToBeAdded,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii}); elseif matches(class(Table.(tmpVariablesToBeAdded{ii})),'cell') tmpContentToBeAdded = repmat({' '},size(TableRowToBeAdded,1),size(Table.(tmpVariablesToBeAdded{ii}),2)); TableRowToBeAdded = addvars(TableRowToBeAdded,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii}); elseif matches(class(Table.(tmpVariablesToBeAdded{ii})),'string') tmpContentToBeAdded = repmat({" "},size(TableRowToBeAdded,1),size(Table.(tmpVariablesToBeAdded{ii}),2)); TableRowToBeAdded = addvars(TableRowToBeAdded,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii}); end end end % Table to be added has more variables if ~all(ismember(TableRowToBeAdded.Properties.VariableNames,Table.Properties.VariableNames)) tmpMissingVariable = ~ismember(TableRowToBeAdded.Properties.VariableNames,Table.Properties.VariableNames); tmpVariablesToBeAdded = TableRowToBeAdded.Properties.VariableNames(tmpMissingVariable); for ii = 1:size(tmpVariablesToBeAdded,2) if matches(class(TableRowToBeAdded.(tmpVariablesToBeAdded{ii})),'double') || matches(class(TableRowToBeAdded.(tmpVariablesToBeAdded{ii})),'int32') tmpContentToBeAdded = NaN(size(Table,1),size(TableRowToBeAdded.(tmpVariablesToBeAdded{ii}),2)); Table = addvars(Table,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii}); elseif matches(class(TableRowToBeAdded.(tmpVariablesToBeAdded{ii})),'cell') tmpContentToBeAdded = repmat({' '},size(Table,1),size(TableRowToBeAdded.(tmpVariablesToBeAdded{ii}),2)); Table = addvars(Table,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii}); elseif matches(class(TableRowToBeAdded.(tmpVariablesToBeAdded{ii})),'string') tmpContentToBeAdded = repmat({" "},size(Table,1),size(TableRowToBeAdded.(tmpVariablesToBeAdded{ii}),2)); Table = addvars(Table,tmpContentToBeAdded,'NewVariableNames',tmpVariablesToBeAdded{ii}); end end end % Reconcile column widths for peak-fit columns. % These numeric columns can have variable width (one entry per peak), % so a width mismatch is expected when spectra have different numbers % of peaks. Pad the narrower side with NaN. variableWidthColumns = {'peakArea', 'peakPosition', 'peakFWHM', ... 'peakBackground', 'peakEta', 'peakShirleyK'}; for ii = 1:numel(variableWidthColumns) varName = variableWidthColumns{ii}; if ~ismember(varName, Table.Properties.VariableNames) || ... ~ismember(varName, TableRowToBeAdded.Properties.VariableNames) continue end widthT = size(Table.(varName), 2); widthR = size(TableRowToBeAdded.(varName), 2); if widthT < widthR Table.(varName) = [Table.(varName), ... NaN(height(Table), widthR - widthT)]; elseif widthR < widthT TableRowToBeAdded.(varName) = [TableRowToBeAdded.(varName), ... NaN(height(TableRowToBeAdded), widthT - widthR)]; end end % Ensure matching column order before concatenation TableRowToBeAdded = TableRowToBeAdded(:, Table.Properties.VariableNames); % Add row to table Table = [Table;TableRowToBeAdded]; end