How to sum structures

46 views (last 30 days)
Joanna Przeworska
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
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.
Joanna Przeworska
Joanna Przeworska on 17 Mar 2021
Dear Stephen,
I thought it is much simpler than it sounded. Sorry for mistaken naming. Yes, after I wrote the answer with screenshots, I realized that you might have been asking for the real data. I attached them but not sure if it's readible.
Thank you for your suggestions. Actually the answear given by Image Analyst works in my case, but I will go one step ahead and try to program it with structfun.
Thank you again,
JP

Sign in to comment.

Accepted Answer

Image Analyst
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
Joanna Przeworska
Joanna Przeworska on 17 Mar 2021
Dear Image Analyst,
Thank you for your suggestion. It works in my case.
Kind regards,
JP
Siddharth Bhutiya
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.

Sign in to comment.

More Answers (2)

Peter Perkins
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
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 = struct with fields:
X: [3×2 table] Y: [3×2 table]
C.X
ans = 3×2 table
X1 X2 ______ ______ 0.965 1.3017 1.1474 1.8184 1.8811 1.2926
C.Y
ans = 3×2 table
Y1 Y2 _______ _______ 1.0575 0.88864 0.40549 0.41229 0.4576 1.6037
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.

Sign in to comment.


Matthew Clay
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)

Categories

Find more on Structures 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!