Suppose that myData
is a list of sublists. Each sublist has a length of one or greater and contains any number of replicates of the integers 1, 2, 3, and 4. I would like to create a function myFun
that counts the number of each integer in the sublist.
As an example, suppose that I have the following myData
:
myData = {{2, 3, 3, 1, 1, 3, 2, 2, 4, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1},
{2, 2, 3, 1, 1, 3, 2, 2, 3, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1, 1},
{1, 2, 2, 1, 1, 3, 2, 1, 3, 1, 1, 2, 2, 2, 2, 3, 1, 1},
{2, 3, 3, 1, 1, 2, 3, 2, 3, 1, 2, 1, 2, 1, 2, 2, 2, 1, 1, 1}};
I would like myFun /@ myData
to return the output:
{{{1, 8}, {2, 8}, {3, 3}, {4, 1}}, {{1, 9}, {2, 8}, {3, 3}, {4, 0}}, {{1, 8}, {2, 7}, {3, 3}, {4, 0}}, {{1, 8}, {2, 8}, {3, 4}, {4, 0}}}
In other words, sublist 1 has eight 1
s, eight 2
s, three 3
s, and one 4
, and similarly for the other three sublists. The key feature here is that all of 1
, 2
, 3
, and 4
are listed, even if one or more of them have zero population.
Using the following (taking advantage of Tally
) gets me close:
myFun[sublist_] := SortBy[Tally[sublist], First]
myFun /@ myData
{{{1, 8}, {2, 8}, {3, 3}, {4, 1}}, {{1, 9}, {2, 8}, {3, 3}}, {{1, 8}, {2, 7}, {3, 3}}, {{1, 8}, {2, 8}, {3, 4}}}
But Tally
does not list members with zero population, so the above does not satisfy the key feature.
On the other hand, the following (using Count
) seems to accomplish my goal:
myFun[sublist_] := Map[{#, Count[sublist, #]} &, {1, 2, 3, 4}]
myFun /@ myData
{{{1, 8}, {2, 8}, {3, 3}, {4, 1}}, {{1, 9}, {2, 8}, {3, 3}, {4, 0}}, {{1, 8}, {2, 7}, {3, 3}, {4, 0}}, {{1, 8}, {2, 8}, {3, 4}, {4, 0}}}
But, is there a more succinct, more elegant way to do this? Thanks for your time!
Outer[Count, myData, {1, 2, 3, 4}, 1]
$\endgroup$