How to sum structures
49 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Joanna Przeworska
el 17 de Mzo. de 2021
Comentada: Siddharth Bhutiya
el 30 de Mzo. de 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 comentarios
Stephen23
el 17 de Mzo. de 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.
Respuesta aceptada
Image Analyst
el 17 de Mzo. de 2021
Editada: Image Analyst
el 17 de Mzo. de 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 comentarios
Siddharth Bhutiya
el 30 de Mzo. de 2023
You no longer need to convert your tables into array to do arithmetic operations, see my comment on Peter's answer below.
Más respuestas (2)
Peter Perkins
el 7 de Dic. de 2021
Editada: Peter Perkins
el 7 de Dic. de 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 comentario
Siddharth Bhutiya
el 30 de Mzo. de 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
el 2 de Dic. de 2022
Editada: Matthew Clay
el 2 de Dic. de 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 comentarios
Ver también
Categorías
Más información sobre Matrices and Arrays en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!