How to sum structures

49 Ansichten (letzte 30 Tage)
Joanna Przeworska
Joanna Przeworska am 17 Mär. 2021
Kommentiert: Siddharth Bhutiya am 30 Mär. 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 Kommentare
Stephen23
Stephen23 am 17 Mär. 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 am 17 Mär. 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

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Image Analyst
Image Analyst am 17 Mär. 2021
Bearbeitet: Image Analyst am 17 Mär. 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 Kommentare
Joanna Przeworska
Joanna Przeworska am 17 Mär. 2021
Dear Image Analyst,
Thank you for your suggestion. It works in my case.
Kind regards,
JP
Siddharth Bhutiya
Siddharth Bhutiya am 30 Mär. 2023
You no longer need to convert your tables into array to do arithmetic operations, see my comment on Peter's answer below.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

Peter Perkins
Peter Perkins am 7 Dez. 2021
Bearbeitet: Peter Perkins am 7 Dez. 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 Kommentar
Siddharth Bhutiya
Siddharth Bhutiya am 30 Mär. 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.

Melden Sie sich an, um zu kommentieren.


Matthew Clay
Matthew Clay am 2 Dez. 2022
Bearbeitet: Matthew Clay am 2 Dez. 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)

Kategorien

Mehr zu Structures finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by