How to sum structures
42 views (last 30 days)
Show older comments
Joanna Przeworska
on 17 Mar 2021
Commented: Siddharth Bhutiya
on 30 Mar 2023
Dear all,
Suppose I have two structures A and B, which inside have the same substructures a, b, c, d, e and each of substructure contains table with 10 variables, lets say: x1, x2, ... x10.
My goal is to generate structure C as a sum of A and B, such that e.g. C.a.x1 = A.a.x1 + B.a.x1, C.a.x2 = A.a.x2 + B.a.x2, ... C.a.x10 = A.a.x10 + B.a.x10 and the same for the remaining substructures. Could you give me simplest way to do this?
6 Comments
Stephen23
on 17 Mar 2021
Note that based on those screenshots:
- There are no nested structures (those are just fields of the structure, not "substructures" as you wrote).
- The two structures actually are scalar (clearly indicated by the "1x1 struct" at the top of the viewer pane). That makes quite a difference!
Uploading data is much more reliable than descriptions: it means that you get help faster.
You can certainly achieve what you want by looping over the fieldnames (see fieldnames to start with). Otherwise with a bit of thought and effort, it is probably possible to leverage structfun to do what you want.
Accepted Answer
Image Analyst
on 17 Mar 2021
Edited: Image Analyst
on 17 Mar 2021
Does doing
x1Sum = sum([A.a.x1] + [B.a.x1])
work? You might have to convert the tables to arrays first with table2array().
Attach your variables in a .mat file if you need more help.
save('answers.mat', 'A', 'B');
2 Comments
Siddharth Bhutiya
on 30 Mar 2023
You no longer need to convert your tables into array to do arithmetic operations, see my comment on Peter's answer below.
More Answers (2)
Peter Perkins
on 7 Dec 2021
Edited: Peter Perkins
on 7 Dec 2021
Assuming that you are starting with something like this
>> A.X = table(rand(3,1),rand(3,1),'VariableNames',{'X1' 'X2'});
>> A.Y = table(rand(3,1),rand(3,1),'VariableNames',{'Y1' 'Y2'});
>> B.X = table(rand(3,1),rand(3,1),'VariableNames',{'X1' 'X2'});
>> B.Y = table(rand(3,1),rand(3,1),'VariableNames',{'Y1' 'Y2'});
>> A.X
ans =
3×2 table
X1 X2
________ _______
0.043024 0.73172
0.16899 0.64775
0.64912 0.45092
>> B.Y
ans =
3×2 table
Y1 Y2
_______ _______
0.48679 0.30635
0.43586 0.50851
0.44678 0.51077
then you don't really need table2array. Here's what I would do:
>> C.X = A.X.Variables + B.X.Variables
C =
struct with fields:
X: [3×2 double]
Y: [3×2 double]
>> C.Y = A.Y.Variables + B.Y.Variables
C =
struct with fields:
X: [3×2 double]
Y: [3×2 double]
>> C.X
ans =
0.41151 0.81285
0.79461 1.5771
1.4293 1.2266
>> C.Y
ans =
1.0338 0.4953
0.73218 1.1953
1.1915 0.69428
This is a lot like what IA suggested, except that instead of needing 10 additions for each pair of tables, you can use .Variables to add them all at once. A.X.Variables is just all the numeric data in A.X horz cat'ed together (it's like table2array, but you can use it inline, and as the LHS of an assignment so you also don't need array2table.)
The fact that these tables are fields of a struct makes this seem complicated, but it isn't. It's just "how do I add the numeric contents of two tables together?" There's a long example in the doc that talks about that kind of "math on tables" question, and more:
If you have more than a handful of fields (the X and Y) in each scalar struct, you might want to avoid a bunch of similar assignments and instead write a loop over the fieldnames, which becomes something like
fn = fieldnames(A);
for i = 1:length(fn)
name = fn{i};
C.(name) = A.(name).Variables + B.(name).Variables;
end
1 Comment
Siddharth Bhutiya
on 30 Mar 2023
In 23a, doing what Peter mentioned above is even simpler. tables now support arithemetic operations (like plus, minus, mean, sum, etc), so you no longer need the .Variables trick that Peter mentioned above. If you are using 23a you can simply do the following:
A.X = table(rand(3,1),rand(3,1),'VariableNames',{'X1' 'X2'});
A.Y = table(rand(3,1),rand(3,1),'VariableNames',{'Y1' 'Y2'});
B.X = table(rand(3,1),rand(3,1),'VariableNames',{'X1' 'X2'});
B.Y = table(rand(3,1),rand(3,1),'VariableNames',{'Y1' 'Y2'});
fn = fieldnames(A);
for i = 1:length(fn)
name = fn{i};
C.(name) = A.(name) + B.(name); % No .Variables needed
end
C
C.X
C.Y
Note that another benefit of this is that the output will also be a table and other metadata like the variable names will also be preserved. You can check out this documentation page for more info.
Matthew Clay
on 2 Dec 2022
Edited: Matthew Clay
on 2 Dec 2022
I've found a way of doing this without loops or tables:
If A and B are structures with the same fieldnames, they can be added together like so:
C = cell2struct(num2cell(struct2array(A) + struct2array(B))',fieldnames(A))
Essentially, the process is:
- Convert the input structures to arrays
- Perform whatever operation you need
- Convert the result to a cell array
- Convert that result back to a struct array (using the same fieldnames as A)
0 Comments
See Also
Categories
Find more on Matrices and Arrays 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!