Seeing as my initial comment seems like a both elegant and fast solution I'll post it as an asnwer. Basically it's just using `Outer` to carry out the same sort of loop you wrote in the last part of your question:

    Outer[{#2, Count[#1, #2]} &, myData, {1, 2, 3, 4}, 1]

I honestly didn't expect it to be faster than solutions written specifically for this task, just though I'd mention it, since this is in my oppinion a nicer way of doing a "double map" over each element in the first list with each element in the last list. But it seems to be acceptable when comparing speeds with the other posted solutions.

Timing this and the other solutions here (using `Do[code,{10000}];//AbsoluteTimin`), I currently get the following timings:

    jVincent      Outer:  0.302000
    Andrew        myFun:  0.344000
    Leonids       myFun:  0.772077
    kgulers     myTally:  0.828083
    Mr. Wizards countBy:  0.965096

So it seems to do just fine with respect to computational efficiency.