Merging lists of pairs [duplicate]

I want to add several fluorescence spectra. They are lists of the format

spectrum 1 = {{x1,y11},{x2,y12},{x3,y13},...}
spectrum 2 = {{x1,y21},{x2,y22},{x3,y23},...}


I want to create a list with the original x-values, but the y-value being the y-value of list 1 + y-value of list 2 + ..., so in code:

result = {{x1,y11+y21},{x2,y12+y22},{x3,y13+y23},...}


Please notice that I will have approx. 50 lists that have to be added, not two.

Additional problem: Some of the lists have different length since they comprise a different wavelength-range. For example a list that doesn't start with x1:

list 7 = {{x4, y71},{x5,y72},{x6,y73},...}


Thanks.

v10 only and using @kglr's spectra...

List @@@ Normal@
GroupBy[Join[spectrum1, spectrum2, spectrum3], First -> Last, Total]


{{x1, y11 + y21}, {x2, y12 + y22}, {x3, y13 + y23 + y33}, {x4, y14 + y24 + y34}, {x5, y15 + y25 + y35}}

• I liked your solution very much. I did import the lists in a table, so that spectrum1=Dataset[[1]]. Can I now somehow loop inside the Join[...]-function, so that I don't explicitly have to write down all the list names in it? Thanks! – keyx Jun 25 '15 at 21:49
• If your data is already in a Dataset, @kglr's Merge solution is probably the best. – kale Jun 25 '15 at 22:09
spectrum1 = {{x1, y11}, {x2, y12}, {x3, y13}, {x4, y14}, {x5, y15}};
spectrum2 = {{x1, y21}, {x2, y22}, {x3, y23}, {x4, y24}, {x5, y25}};
spectrum3 = {{x3, y33}, {x4, y34}, {x5, y35}};


GatherBy

{#[[All,1]][[1]],Total@#[[All,-1]]}&/@GatherBy[Join[spectrum1,spectrum2,spectrum3],First]


{{x1, y11 + y21}, {x2, y12 + y22}, {x3, y13 + y23 + y33},
{x4, y14 + y24 + y34}, {x5, y15 + y25 + y35}}

Merge

asso=Association@@Rule@@@#&/@{spectrum1,spectrum2,spectrum3};
List@@@Normal@Merge[asso, Total]


or

List@@@Normal@Merge[Total][Rule@@@Join[spectrum1,spectrum2,spectrum3]]


{{x1, y11 + y21}, {x2, y12 + y22}, {x3, y13 + y23 + y33},
{x4, y14 + y24 + y34}, {x5, y15 + y25 + y35}}

If they have the same length, one way would be using patterns. For example for 3 spectra:

spectrum1 = {{x1, y11}, {x2, y12}, {x3, y13}};
spectrum2 = {{x1, y21}, {x2, y22}, {x3, y23}};
spectrum3 = {{x1, y31}, {x2, y32}, {x3, y33}};


You write:

(spectrum1 + spectrum2 + spectrum3) /. {a_, b_} -> {a/3, b}


and you get:

{{x1, y11 + y21 + y31}, {x2, y12 + y22 + y32}, {x3, y13 + y23 + y33}}


If they don't have the same length, you can gather them based on first element, for example:

spectrum1 = {{x1, y11}, {x2, y12}, {x3, y13}};
spectrum2 = {{x1, y21}, {x2, y22}, {x3, y23}};
spectrum3 = {{x1, y31}, {x2, y32}, {x3, y33}};
spectrum7 = {{x4, y71}, {x5, y72}, {x6, y73}};

pts = GatherBy[Join[spectrum1, spectrum2, spectrum3, spectrum7], First]


to get:

{{{x1, y11}, {x1, y21}, {x1, y31}}, {{x2, y12}, {x2, y22}, {x2,
y32}}, {{x3, y13}, {x3, y23}, {x3, y33}}, {{x4, y71}}, {{x5,
y72}}, {{x6, y73}}}


and finally:

 {First[#], Total@Rest[#]} & /@ (Union @@@ pts)

{{x1, y11 + y21 + y31}, {x2, y12 + y22 + y32}, {x3,
y13 + y23 + y33}, {x4, y71}, {x5, y72}, {x6, y73}}

• Using Union potentially leads to erroneous results, when actual spectra (with numerical values) are used. If, e.g., y23==y13, than one of them will get removed from the final result. – Karsten 7. Jun 25 '15 at 21:19