Say, I'm given a dataset, like the one below:

titanic = ExampleData[{"Dataset", "Titanic"}]; titanic

Answering with:

Sample of the Titanic example data

And I want to count the occurrences of any combination between { "1st", "2nd"} and {"female", "male"}, using the Counts operator on the dataset, like:

genderclasscounts = titanic[All, {"class", "sex"}][Counts]

Gender Class combination counts

Problem statement

This is not a "flat" dataset and I don't have a clue how to query in the usual way, like:

genderclasscount[Select[ ... ], ...]

The resulting dataset doesn't provide "column" names to be used as parameters in the Select nor can I refer to the number representing the count by a name.

And I've no clue how to express an Association as a value in a Select!?

Furthermore, try genderclasscount[Print], this demonstrates the values presented to the operation over this dataset are just numbers!

An unsatisfactory attempt

Of course, I can "flatten" the Counts result, by doing something horrific and inefficient like:

temp = Dataset[(row \[Function] 
     AssociationThread[{"class", "sex", "count"} -> row]) /@ (Nest[
      Normal, genderclasscounts, 3] /. 
     Rule[{Rule["class", class_], Rule["sex", sex_]}, 
       count_] -> {class, sex, count})]

Flattened Counts over a dataset result

In this form it is easy to query a count result:

First@temp[Select[#class == "1st" \[And] #sex == "female" &], "count"]


So, my questions are

  1. How can I query the (immediate) result of the Count operation in a convenient and efficient fashion, like using a Select operation on the resulting dataset? Or, if that is not possible;

  2. Is there an efficient and convenient transformation of the Counts result dataset possible facilitating such a query? With "convenient" I mean, for example, that you just provide the dataset and the transformation handles the rest. So, not something like I've shown above in my unsatisfactory "solution" ;-)

Thanks for reading this far and I'm looking forward to anwsers and inspiration.



1 Answer 1

titanic[KeyValueMap[Append[#, "counts" -> #2] &]@*Counts, {"class", "sex"}]

enter image description here

  • 1
    $\begingroup$ Thanks. It is certainly more efficient than my own kludge and it is convenient in its brevity. And to boot, it opens up some new insight how to use datasets. Again thanks!. Not in anyway intended to diminish your solution, a little thing is bugging me terse as your solution is, it feels rather alien to me. Is there some way of reasoning here assisting you in coming up with such a solution? Other than sheer brainpower and experience ;-) $\endgroup$
    – nanitous
    Commented May 22, 2020 at 12:28
  • $\begingroup$ @nanitous, thank you for the accept. Re reasoning behind, squinting at Normal[titanic[Counts,{"class", "sex"}] realized something like KeyValueMap might work. $\endgroup$
    – kglr
    Commented May 22, 2020 at 13:03
  • $\begingroup$ Well, your answer gave me probably the same insight. But way later ;-) $\endgroup$
    – nanitous
    Commented May 22, 2020 at 13:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.