user2372443
user2372443

Reputation: 27

Using data returned form Tally command in Mathematica

I have a small piece of code to generate sequences, which is ok.

List = Reap[
    For[i = 1, i <= 10000, i++, 
      Sow[RandomSample[Join[Table["a", {2}], Table["b", {2}]],  2]]];][[2, 1]];
Tally[List]

Giving the following output,

{{{"b", "b"}, 166302}, {{"b", "a"}, 333668}, {{"a", "b"}, 332964}, {{"a", "a"}, 167066}}

My problem is I have yet to find a way to extract the frequencies from the output ....?

Thanks in advance for any help

Upvotes: 0

Views: 509

Answers (1)

Mr.Wizard
Mr.Wizard

Reputation: 24336

Note: Generally do not start user-created Symbol names with a capital letter as these may conflict with internal functions.

It is not clear to me how you wish to transform the output. One interpretation is that you just want:

{166302, 333668, 332964, 167066}

In your code you use [[2, 1]] so I presume you know how to use Part, of which this is a short form. The documentation for Part includes:

If any of the listi are All or ;;, all parts at that level are kept.

You could therefore use:

Tally[list][[All, 2]]

You could also use:

Last /@ Tally[list]

As george comments you can use Sort, which due to the structure of the Tally data will sort first by the item because it appears first in each list, and each list has the same length.

tally = 
 {{{"b","b"},166302},{{"b","a"},333668},{{"a","b"},332964},{{"a","a"},167066}};

Sort[tally][[All, 2]]
{167066, 332964, 333668, 166302}

You could also convert your data into a list of Rule objects and then pull values from a predetermined list:

rules = Rule @@@ tally
{{"b", "b"} -> 166302, {"b", "a"} -> 333668, {"a", "b"} -> 332964, {"a", "a"} -> 167066}

These could be in any order you choose:

{{"a", "a"}, {"a", "b"}, {"b", "a"}, {"b", "b"}} /. rules
{167066, 332964, 333668, 166302}

Merely to illustrate another technique if you have a specific list of items you wish to count you may find value in this Sow and Reap construct. For example, with a random list of "a", "b", "c", "d":

SeedRandom[1];
dat = RandomChoice[{"a", "b", "c", "d"}, 50];

Counting the "a" and "c" elements:

Reap[Sow[1, dat], {"a", "c"}, Tr[#2] &][[2, All, 1]]
{19, 5}

This is not as fast as Tally but it is faster than doing a Count for each element, and sometimes the syntax is useful.

Upvotes: 2

Related Questions