# Adding $y$ values based on the value of $x$ in a list

I have the following list consisting of a specified number of $(x,y)$ coordinates. Now I want to add the values of $y$ for which the $x$ values are same. For e.g. I want to convert the list $\{\{2,5\},\{2,7\},\{2,9\},\{3,1\},\{3,5\},\{4,2\}\}$ to $\{\{2,21\},\{3,6\},\{4,2\}\}$. Any guidance on how to go about this would be appreciated.

data = {{34, 1.35525*10^-20}, {35, 0}, {36, 8.94467*10^-19}, {37, 0},
{38,2.90702*10^-17}, {39, 0}, {40, 6.20164*10^-16}, {41, 0}, {42,
9.76758*10^-15}, {43, 0}, {44, 1.21118*10^-13}, {45, 0},
{46,1.23137*10^-12}, {47, 0}, {48, 1.05546*10^-11}, {49, 0}, {0,
7.78399*10^-11}, {1, 0}, {2, 5.01635*10^-10}, {3, 0}, {4,
2.85932*10^-9}, {5, 0}, {6, 1.45565*10^-8}, {7, 0}, {8, 6.67175*10^-8},
{9,0}, {10, 2.77134*10^-7}, {11, 0}, {12, 1.04915*10^-6}, {13, 0},
{14,3.63705*10^-6}, {15, 0}, {16, 0.0000115931}, {17, 0}, {18,
0.0000340974}, {19, 0}, {20, 0.0000928207}, {21, 0}, {22, 0.000234494}, {23,
0}, {24, 0.000551062}, {25, 0}, {26, 0.00120709}, {27, 0}, {28, 0.00246904},
{29, 0}, {30, 0.00472339}, {31, 0}, {32, 0.00846273}, {33, 0}, {34,
0.0142174}, {35, 0}, {36, 0.0224197}, {37, 0}, {38, 0.0332144}, {39, 0},{40,
0.0462629}, {41, 0}, {42, 0.0606204}, {43, 0}, {44, 0.0747652}, {45, 0},
{46, 0.0868241}, {47, 0}, {48, 0.0949638}, {49, 0}, {0, 0.0978415}, {1,
0}, {2, 0.0949638}, {3, 0}, {4, 0.0868241}, {5, 0}, {6, 0.0747652}, {7, 0},
{8, 0.0606204}, {9, 0}, {10, 0.0462629}, {11, 0}, {12, 0.0332144}, {13, 0},
{14, 0.0224197}, {15, 0}, {16, 0.0142174}, {17, 0}, {18, 0.00846273}, {19,
0}, {20, 0.00472339}, {21, 0}, {22, 0.00246904}, {23, 0}, {24, 0.00120709},
{25, 0}, {26, 0.000551062}, {27, 0}, {28, 0.000234494}, {29, 0}, {30,
0.0000928207}, {31, 0}, {32, 0.0000340974}, {33, 0}, {34, 0.0000115931},
{35, 0}, {36, 3.63705*10^-6}, {37, 0}, {38, 1.04915*10^-6}, {39, 0}, {40,
2.77134*10^-7}, {41, 0}, {42, 6.67175*10^-8}, {43, 0}, {44, 1.45565*10^-8},
{45, 0}, {46, 2.85932*10^-9}, {47, 0}, {48, 5.01635*10^-10}, {49, 0}, {0,
7.78399*10^-11}, {1, 0}, {2, 1.05546*10^-11}, {3, 0}, {4, 1.23137*10^-12},
{5, 0}, {6, 1.21118*10^-13}, {7, 0}, {8, 9.76758*10^-15}, {9, 0}, {10,
6.20164*10^-16}, {11, 0}, {12, 2.90702*10^-17}, {13, 0}, {14,
8.94467*10^-19}, {15, 0}, {16, 1.35525*10^-20}}

Try this:

KeySort[GroupBy[data, First -> Last, Total]]
list = Values[assoc]

<|0 -> 0.0978415, 1 -> 0, 2 -> 0.0949638, 3 -> 0, 4 -> 0.0868241, 5 -> 0, 6 -> 0.0747652, 7 -> 0, 8 -> 0.0606205, 9 -> 0, 10 -> 0.0462632, 11 -> 0, 12 -> 0.0332154, 13 -> 0, 14 -> 0.0224233, 15 -> 0, 16 -> 0.014229, 17 -> 0, 18 -> 0.00849683, 19 -> 0, 20 -> 0.00481621, 21 -> 0, 22 -> 0.00270353, 23 -> 0, 24 -> 0.00175815, 25 -> 0, 26 -> 0.00175815, 27 -> 0, 28 -> 0.00270353, 29 -> 0, 30 -> 0.00481621, 31 -> 0, 32 -> 0.00849683, 33 -> 0, 34 -> 0.014229, 35 -> 0, 36 -> 0.0224233, 37 -> 0, 38 -> 0.0332154, 39 -> 0, 40 -> 0.0462632, 41 -> 0, 42 -> 0.0606205, 43 -> 0, 44 -> 0.0747652, 45 -> 0, 46 -> 0.0868241, 47 -> 0, 48 -> 0.0949638, 49 -> 0|>

{0.0978415, 0, 0.0949638, 0, 0.0868241, 0, 0.0747652, 0, 0.0606205, 0, 0.0462632, 0, 0.0332154, 0, 0.0224233, 0, 0.014229, 0, 0.00849683, 0, 0.00481621, 0, 0.00270353, 0, 0.00175815, 0, 0.00175815, 0, 0.00270353, 0, 0.00481621, 0, 0.00849683, 0, 0.014229, 0, 0.0224233, 0, 0.0332154, 0, 0.0462632, 0, 0.0606205, 0, 0.0747652, 0, 0.0868241, 0, 0.0949638, 0}

I also provide a method that employs SparseArray with additive assembly. This should be faster for very long datasets.

list = With[{spopt = SystemOptions["SparseArrayOptions"]},
Internal`WithLocalSettings[
SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> Total}],

Normal[SparseArray[Partition[data[[All, 1]], 1] + 1 -> data[[All, 2]]]],

SetSystemOptions[spopt]]
]

Another method

{#[[1, 1]], Total@#[[;; , 2]]} & /@ GatherBy[data, First] // Sort

{{0, 0.0978415}, {1, 0}, {2, 0.0949638}, {3, 0}, {4, 0.0868241}, {5, 0}, {6, 0.0747652}, {7, 0}, {8, 0.0606205}, {9, 0}, {10, 0.0462632}, {11, 0}, {12, 0.0332154}, {13, 0}, {14, 0.0224233}, {15, 0}, {16, 0.014229}, {17, 0}, {18, 0.00849683}, {19, 0}, {20, 0.00481621}, {21, 0}, {22, 0.00270353}, {23, 0}, {24, 0.00175815}, {25, 0}, {26, 0.00175815}, {27, 0}, {28, 0.00270353}, {29, 0}, {30, 0.00481621}, {31, 0}, {32, 0.00849683}, {33, 0}, {34, 0.014229}, {35, 0}, {36, 0.0224233}, {37, 0}, {38, 0.0332154}, {39, 0}, {40, 0.0462632}, {41, 0}, {42, 0.0606205}, {43, 0}, {44, 0.0747652}, {45, 0}, {46, 0.0868241}, {47, 0}, {48, 0.0949638}, {49, 0}}

One way to approach this is to select all the terms with identical first elements, and add the second elements together:

tl = Union[Transpose[data][[1]]];
Table[{i, Total[Transpose[Select[data, #[[1]] == i &]][[2]]]}, {i, tl}]

For the simple case:

data = {{2, 5}, {2, 7}, {2, 9}, {3, 1}, {3, 5}, {4, 2}};

this gives

{{2, 21}, {3, 6}, {4, 2}}

We can use SplitBy

{#[[1, 1]], Total@#[[All, 2]]} & /@ SplitBy[Sort@data, First]

{{0, 0.0978415}, {1, 0}, {2, 0.0949638}, {3, 0}, {4, 0.0868241}, {5, 0}, {6, 0.0747652}, {7, 0}, {8, 0.0606205}, {9, 0}, {10, 0.0462632}, {11, 0}, {12, 0.0332154}, {13, 0}, {14, 0.0224233}, {15, 0}, {16, 0.014229}, {17, 0}, {18, 0.00849683}, {19, 0}, {20, 0.00481621}, {21, 0}, {22, 0.00270353}, {23, 0}, {24, 0.00175815}, {25, 0}, {26, 0.00175815}, {27, 0}, {28, 0.00270353}, {29, 0}, {30, 0.00481621}, {31, 0}, {32, 0.00849683}, {33, 0}, {34, 0.014229}, {35, 0}, {36, 0.0224233}, {37, 0}, {38, 0.0332154}, {39, 0}, {40, 0.0462632}, {41, 0}, {42, 0.0606205}, {43, 0}, {44, 0.0747652}, {45, 0}, {46, 0.0868241}, {47, 0}, {48, 0.0949638}, {49, 0}}