Accumulate second elements in sublist

Similar in idea to Hassler Thurston's, different in style:

acc[l_List] := Module[{reg, f},
  reg[_] = 0; (* register reg[x] stores the current total for index x *)
  SetAttributes[f, Listable];
  {f[x_], f[a_]} ^:= {x, reg[x] = reg[x] + a};
  f[l]
  ]

OP's example:

list = {{{1, 1}}, {{2, 1}}, {{3, 1}}, {{2, 2}}, {{5, 1}}, {{2, 1}, {3,
      1}}, {{7, 1}}, {{2, 3}}, {{3, 2}}, {{2, 1}, {5, 1}}, {{11, 
     1}}, {{2, 2}, {3, 1}}, {{13, 1}}, {{2, 1}, {7, 1}}, {{3, 1}, {5, 
     1}}, {{2, 4}}, {{17, 1}}, {{2, 1}, {3, 2}}};

acc[list]
(*
  {{{1, 1}}, {{2, 1}}, {{3, 1}}, {{2, 3}}, {{5, 1}}, {{2, 4}, {3, 2}},
    {{7, 1}}, {{2, 7}}, {{3, 4}}, {{2, 8}, {5, 2}}, {{11, 1}},
    {{2, 10}, {3, 5}}, {{13, 1}}, {{2, 11}, {7, 2}}, {{3, 6}, {5, 3}},
    {{2, 15}}, {{17, 1}}, {{2, 16}, {3, 8}}}
*)

For each "first element", keep a count of its accumulation:

SecondLevelAccumulation[list_] := Module[{counts, replace},
    counts = {};
    replace[tuple_] := Module[{},
        (* If we've never seen a "first element", initialize its count to 0 *)
        If[! MemberQ[counts[[All, 1]], tuple[[1]]],
            AppendTo[counts, tuple[[1]] -> 0]];
        (* Then update the count to reflect the tuple's second element *)
        counts = counts /. {(tuple[[1]] -> a_) :> (tuple[[1]] -> a + tuple[[2]])};
        (* Finally, replace the second element of the given tuple to its accumulation *)
        {tuple[[1]], tuple[[1]]/.counts}
    ];
    (* As a last step, map the replace function to the original list at level 2 *)
    Map[replace, list, {2}]
]

Result:

Results


Michael posted a good method but it uses the Listable Attribute and UpSetDelayed (^:=) which are both fairly advanced concepts. Since I know that you are in the process of learning Mathematica let me show you that these methods are simply not necessary here.

I too will use the simple counter construct I often do(1),(2) and which is discussed in More efficient way of generating list of occurrence counts?

Fundamentally I shall be using a pattern and I shall need to restrict it(3)(4); I shall show both levelspec and purely pattern based approaches.

For all examples I have assigned your input expression to data.

levelspec in Replace:

Module[{count},
  count[_] = 0;
  Replace[data, {i_, n_} :> {i, count[i] += n}, {2}]
]

Pattern only in ReplaceAll:

Module[{count},
  count[_] = 0;
  data /. {i_, n_Integer} :> {i, count[i] += n}
]

In addition to these examples you may find it interesting that the counter need not be localized, e.g. with Module, should you actually want to apply it globally:

count[_] = 0;
fn = # /. {i_, n_Integer} :> {i, count[i] += n} &;

Now:

fn @ {{1, 1}, {2, 1}, {3, 1}}
fn @ {{3, 4}, {5, 1}}
fn @ {{2, 2}, {3, 1}}
{{1, 1}, {2, 1}, {3, 1}}

{{3, 5}, {5, 1}}

{{2, 3}, {3, 6}}

To resent the counter you can use this:

ClearAll[count]; count[_] = 0;