assign the fields of a structure correctly

2 views (last 30 days)
h, i want to add d1 to table
app.Preset_UITable.Data(end+1,:)=d1; %===> it's not correct because the fields have a different order
How can I add the preset to the table by correctly assign the fields?

Accepted Answer

Voss
Voss on 8 Sep 2024
Edited: Voss on 8 Sep 2024
Assuming the set of table variable names is the same between d1 and app.Preset_UITable.Data (but potentially in a different order):
[~,idx] = ismember(app.Preset_UITable.Data.Properties.VariableNames,d1.Properties.VariableNames);
app.Preset_UITable.Data(end+1,:) = d1(:,idx);

More Answers (4)

Peter Perkins
Peter Perkins on 10 Sep 2024
Most of what's being shown in the responses is unnecessary. It's easier than that. No loops needed, not even ismember.
1) vertcat will align by variable name:
t = table("Preset_1",false,31,VariableNames=["Name" "LS" "Dwmy"])
t = 1x3 table
Name LS Dwmy __________ _____ ____ "Preset_1" false 31
d1 = table("Preset_2",31,true,VariableNames=["Name" "Dwmy" "LS"])
d1 = 1x3 table
Name Dwmy LS __________ ____ _____ "Preset_2" 31 true
[t; d1]
ans = 2x3 table
Name LS Dwmy __________ _____ ____ "Preset_1" false 31 "Preset_2" true 31
2) Assignment with indices or : on the LHS will assign positionally, which I gather is not what you want:
t(end+1,:) = d1
t = 2x3 table
Name LS Dwmy __________ _____ ____ "Preset_1" false 31 "Preset_2" true 1
In this case, it's positionally assigning 31 into a logical variable (becomes true), and true into an integer variable (becomes 1).
3) Assignment with variable names on the LHS will align:
t(end+1,d1.Properties.VariableNames) = d1
t = 3x3 table
Name LS Dwmy __________ _____ ____ "Preset_1" false 31 "Preset_2" true 1 "Preset_2" true 31

dpb
dpb on 8 Sep 2024
Edited: dpb on 8 Sep 2024
Why is d1 in the reversed order? Why don't you make life simpler and reorder it to match (or vice versa with the table)?
Failing in that, at least one awkward way...
outOrder=[1:width(d1)-2 width(d1) width(d1)-1];
app.Preset_UITable.Data(end+1,outOrder)=d1;
Alternatively,
[~,ib]=ismember(app.Preset_UITable.Properties.VariableNames,d1.Properties.VariableNames);
app.Preset_UITable.Data(end+1,ib)=d1;
  1 Comment
Luca Re
Luca Re on 8 Sep 2024
Moved: dpb on 8 Sep 2024
"d1" is a table filled with fields that may not be sorted. The reason is that individual fields can be added or removed by changing their order Your solutions consist of recreating the correct order during assignment but I wanted an automatic way to assign each field correctly
None of the 2 proposed solutions help me
(there are more than 3 fields, I just simplified it)

Sign in to comment.


Steven Lord
Steven Lord on 8 Sep 2024
Is d1 a struct array whose fields you need to rearrange?
d1 = dir(which('bench.m'))
d1 = struct with fields:
name: 'bench.m' folder: '/MATLAB/toolbox/matlab/general' date: '19-Jul-2023 18:24:31' bytes: 14171 isdir: 0 datenum: 7.3909e+05
If so you can use orderfields. I'm going to use fieldnames to get the list of fields in the struct and reorder them in alphabetical order, but if you have a desired order that you generated some other way you could use that order instead.
thefields = fieldnames(d1);
d2 = orderfields(d1, sort(thefields))
d2 = struct with fields:
bytes: 14171 date: '19-Jul-2023 18:24:31' datenum: 7.3909e+05 folder: '/MATLAB/toolbox/matlab/general' isdir: 0 name: 'bench.m'

Umar
Umar on 8 Sep 2024

Hi @Luca Re,

You mentioned, “"d1" is a table filled with fields that may not be sorted. The reason is that individual fields can be added or removed by changing their order Your solutions consist of recreating the correct order during assignment but I wanted an automatic way to assign each field correctly,None of the 2 proposed solutions help me, (there are more than 3 fields, I just simplified it)”

To address the issue of dynamically assigning fields from one table to another in MATLAB while ensuring that the fields are correctly matched regardless of their order, you can use the following approach. This method involves utilizing MATLAB's ability to handle tables flexibly. Here is a sample code snippet to achieve automatic field assignment:

% Create a sample UI figure and table with initial data
f = uifigure();
app.Preset_UITable = uitable(f, 'Data', table("Preset_1", false,
31, 
'VariableNames', {'Name', 'LS_', 'Dwmy'}));
% New data to be added with potentially different field order
d1 = table("Preset_2", 31, true, 'VariableNames', {'Dwmy', 
'Name', 'LS_'});
% Get the variable names from the existing table
existingVarNames = 
app.Preset_UITable.Data.Properties.VariableNames;
% Initialize an empty array for new data
newRow = cell(1, length(existingVarNames));
% Loop through the existing variable names to fill in the new row
for i = 1:length(existingVarNames)
  % Check if the current variable name exists in d1
  if ismember(existingVarNames{i}, d1.Properties.VariableNames)
      % Assign the corresponding value from d1 to newRow
      newRow{i} = d1{:, existingVarNames{i}};
  else
      % If the variable does not exist, assign a default value 
  (e.g., NaN or empty)
      newRow{i} = NaN;  % You can choose a different default 
 value as needed
  end
end
% Add the new row to the existing table data
app.Preset_UITable.Data(end+1, :) = newRow;
% Display updated table data
disp(app.Preset_UITable.Data);

I am unable to execute this code in Matlab mobile, please see attached. So, please execute this code in your MATLAB program and let me know if this helped resolve your problem.

Explanation of the Code

Table Creation: The code starts by creating a UI figure and an initial table with a specified field order.

New Data Table (d1): A new table `d1` is created with a different order of fields. The goal is to integrate this table into the existing UI table without manual reordering.

Variable Names Extraction: The existing table's variable names are extracted to ensure the new data is assigned in the correct format.

Row Initialization: An empty cell array newRow is initialized to store the values for the new row that will be added.

Field Matching Loop: A loop iterates through the existing table's variable names. For each variable name, the code checks if it exists in d1. If it does, it assigns the corresponding value from d1 to newRow. If the field is missing in d1, a default value is assigned (in this case, NaN).

Data Addition: Finally, the new row is appended to the existing table data in app.Preset_UITable.

Display Output: The updated table data is displayed to confirm the changes.

As you can glance the the code, you will find out that The use of ismember allows the code to adapt to varying field orders, making it robust against changes in the structure of the data. By following this approach, you should be able to add data to your table while making sure that the fields are assigned correctly, regardless of their order.

Categories

Find more on Characters and Strings in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!