You can still use your original strategy, just add a list of unique elements you wish to track, to your sublists, and then adjust the counts. You can add a second definition to your original `myFun`, which would take a list of tracked elements as a second parameter, as follows: ClearAll[myFun]; myFun[sublist_] := SortBy[Tally[sublist], First] myFun[sublist_, elems_] := Replace[myFun[sublist~Join~elems], {el : Alternatives @@ elems, n_} :> {el, n - 1}, 1]; Then, myFun[#, {1, 2, 3, 4}] & /@ myData produces the result you desire. **EDIT** Since the performance issue came up, I have to mention that the above solution is suboptimal, but not due to `Tally`, but rather due to the use of `Alternatives @@ elems`, which makes its complexity to be `O(Length[elems] * Length[sublist])`. Here is a much faster one: ClearAll[myFun1,leonid1]; myFun1[sublist_, elems_] := Module[{tallyT = Transpose@Tally[elems ~ Join ~ sublist], range = Range[Length[elems]]}, tallyT[[2, range ]] = tallyT[[2, range ]] - 1; SortBy[Transpose[tallyT], First] ]; leonid1[dat_, bins_] := myFun1[#, bins] & /@ dat from what I could see, it is the fastest so far. I save big because I put `elems` in front, and so, since `Tally` does its counts in the order it meets the elements, I know precisely the positions of elements where I need to adjust the counts. And I sort the result afterwards.