Better way to sort course grades

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite












I use the following code to create a histogram of grades. Grades are provided as a List of strings such as "A-", "D+", "E" (don't ask), etc. The +/- substitution hack is necessary to sort the grades in my desired order.



f[s_String] := 
If[StringLength@s == 1, s <> "b",
StringReplace[s, "+" -> "a", "-" -> "c"]];
g[s_String] := StringReplace[s, "a" -> "+", "b" -> "", "c" -> "-"];
Reverse@Sort@
Tally@(f /@ "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+",
"C-", "B", "C", "B-", "C+", "E", "B-", "B-", "C-", "A", "C",
"B-", "B", "C+", "B", "C", "B+", "C+", "D-", "C", "A", "E", "B",
"B+", "C", "C", "D+", "D", "C", "C-", "C", "B", "D", "B", "B",
"E", "B", "W", "W")
BarChart[Last /@ %, ChartLabels -> g /@ First /@ %]

(* "Wb", 2, "Eb", 4, "Dc", 1, "Db", 3, "Da", 2, "Cc",
4, "Cb", 9, "Ca", 3, "Bc", 5, "Bb", 11, "Ba", 3, "Ab",
2 *)


enter image description here



I'm looking for a less hackish way to do this. Any suggestions?










share|improve this question





















  • ""E" (don't ask)" - that's as effective as saying "don't think of a polka-dotted elephant" ;) Less facetiously: the sorting order is B- < B < B+, correct?
    – J. M. is somewhat okay.♦
    55 mins ago















up vote
2
down vote

favorite












I use the following code to create a histogram of grades. Grades are provided as a List of strings such as "A-", "D+", "E" (don't ask), etc. The +/- substitution hack is necessary to sort the grades in my desired order.



f[s_String] := 
If[StringLength@s == 1, s <> "b",
StringReplace[s, "+" -> "a", "-" -> "c"]];
g[s_String] := StringReplace[s, "a" -> "+", "b" -> "", "c" -> "-"];
Reverse@Sort@
Tally@(f /@ "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+",
"C-", "B", "C", "B-", "C+", "E", "B-", "B-", "C-", "A", "C",
"B-", "B", "C+", "B", "C", "B+", "C+", "D-", "C", "A", "E", "B",
"B+", "C", "C", "D+", "D", "C", "C-", "C", "B", "D", "B", "B",
"E", "B", "W", "W")
BarChart[Last /@ %, ChartLabels -> g /@ First /@ %]

(* "Wb", 2, "Eb", 4, "Dc", 1, "Db", 3, "Da", 2, "Cc",
4, "Cb", 9, "Ca", 3, "Bc", 5, "Bb", 11, "Ba", 3, "Ab",
2 *)


enter image description here



I'm looking for a less hackish way to do this. Any suggestions?










share|improve this question





















  • ""E" (don't ask)" - that's as effective as saying "don't think of a polka-dotted elephant" ;) Less facetiously: the sorting order is B- < B < B+, correct?
    – J. M. is somewhat okay.♦
    55 mins ago













up vote
2
down vote

favorite









up vote
2
down vote

favorite











I use the following code to create a histogram of grades. Grades are provided as a List of strings such as "A-", "D+", "E" (don't ask), etc. The +/- substitution hack is necessary to sort the grades in my desired order.



f[s_String] := 
If[StringLength@s == 1, s <> "b",
StringReplace[s, "+" -> "a", "-" -> "c"]];
g[s_String] := StringReplace[s, "a" -> "+", "b" -> "", "c" -> "-"];
Reverse@Sort@
Tally@(f /@ "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+",
"C-", "B", "C", "B-", "C+", "E", "B-", "B-", "C-", "A", "C",
"B-", "B", "C+", "B", "C", "B+", "C+", "D-", "C", "A", "E", "B",
"B+", "C", "C", "D+", "D", "C", "C-", "C", "B", "D", "B", "B",
"E", "B", "W", "W")
BarChart[Last /@ %, ChartLabels -> g /@ First /@ %]

(* "Wb", 2, "Eb", 4, "Dc", 1, "Db", 3, "Da", 2, "Cc",
4, "Cb", 9, "Ca", 3, "Bc", 5, "Bb", 11, "Ba", 3, "Ab",
2 *)


enter image description here



I'm looking for a less hackish way to do this. Any suggestions?










share|improve this question













I use the following code to create a histogram of grades. Grades are provided as a List of strings such as "A-", "D+", "E" (don't ask), etc. The +/- substitution hack is necessary to sort the grades in my desired order.



f[s_String] := 
If[StringLength@s == 1, s <> "b",
StringReplace[s, "+" -> "a", "-" -> "c"]];
g[s_String] := StringReplace[s, "a" -> "+", "b" -> "", "c" -> "-"];
Reverse@Sort@
Tally@(f /@ "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+",
"C-", "B", "C", "B-", "C+", "E", "B-", "B-", "C-", "A", "C",
"B-", "B", "C+", "B", "C", "B+", "C+", "D-", "C", "A", "E", "B",
"B+", "C", "C", "D+", "D", "C", "C-", "C", "B", "D", "B", "B",
"E", "B", "W", "W")
BarChart[Last /@ %, ChartLabels -> g /@ First /@ %]

(* "Wb", 2, "Eb", 4, "Dc", 1, "Db", 3, "Da", 2, "Cc",
4, "Cb", 9, "Ca", 3, "Bc", 5, "Bb", 11, "Ba", 3, "Ab",
2 *)


enter image description here



I'm looking for a less hackish way to do this. Any suggestions?







code-review sorting






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 58 mins ago









bobthechemist

14k441110




14k441110











  • ""E" (don't ask)" - that's as effective as saying "don't think of a polka-dotted elephant" ;) Less facetiously: the sorting order is B- < B < B+, correct?
    – J. M. is somewhat okay.♦
    55 mins ago

















  • ""E" (don't ask)" - that's as effective as saying "don't think of a polka-dotted elephant" ;) Less facetiously: the sorting order is B- < B < B+, correct?
    – J. M. is somewhat okay.♦
    55 mins ago
















""E" (don't ask)" - that's as effective as saying "don't think of a polka-dotted elephant" ;) Less facetiously: the sorting order is B- < B < B+, correct?
– J. M. is somewhat okay.♦
55 mins ago





""E" (don't ask)" - that's as effective as saying "don't think of a polka-dotted elephant" ;) Less facetiously: the sorting order is B- < B < B+, correct?
– J. M. is somewhat okay.♦
55 mins ago











3 Answers
3






active

oldest

votes

















up vote
2
down vote













This is a great use for the Association data structure, which makes so many tasks in Mathematica that much more pleasant.



First, we can just write out a ranking of grades:



ranking = "A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", 
"D", "D-", "E", "W";


Then we take your grades and count how many of each there are into an association with Counts:



grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", 
"B", "C", "B-", "C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B",
"C+", "B", "C", "B+", "C+", "D-", "C", "A", "E", "B", "B+", "C",
"C", "D+", "D", "C", "C-", "C", "B", "D", "B", "B", "E", "B", "W",
"W";

counts = Counts[grades]
(* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4, "E" -> 4,
"D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1, "W" -> 2|> *)


This is a table associating each grades with its counts, but it's an a useless order. Let's put it in the order you want, using KeyTake, which we can pass directly to BarChart, which can Automaticly figure out the labels:



ordered = KeyTake[Counts[grades], Reverse@ranking]
(* <|"W" -> 2, "E" -> 4, "D-" -> 1, "D" -> 3, "D+" -> 2, "C-" -> 4,
"C" -> 9, "C+" -> 3, "B-" -> 5, "B" -> 11, "B+" -> 3, "A" -> 2|> *)

BarChart[ordered, ChartLabels -> Automatic]


bar chart






share|improve this answer
















  • 1




    Neat use of Association!
    – J. M. is somewhat okay.♦
    25 mins ago






  • 1




    Sorry, I had a stale window that was open for a while, and did not see your answer ...
    – Szabolcs
    15 mins ago










  • @Szabolcs Haha jinx!
    – Pillsy
    10 mins ago


















up vote
1
down vote













Let's write a custom ordering function that Sort can use:



gradeOrder[g1_, g2_] := Block[ord,
ord = -Order[StringTake[g1, 1], StringTake[g2, 1]];
If[ord != 0, ord,
Which[StringLength[g1] == 1, 2 Boole[StringMatchQ[g2, "*+"]] - 1,
StringLength[g2] == 1, 2 Boole[StringMatchQ[g1, "*-"]] - 1,
True, Order[StringTake[g1, 2], StringTake[g2, 2]]]]]


With this:



grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", "B", "C", "B-",
"C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B", "C+", "B", "C", "B+", "C+",
"D-", "C", "A", "E", "B", "B+", "C", "C", "D+", "D", "C", "C-", "C", "B", "D",
"B", "B", "E", "B", "W", "W";


Then,



gl, nl = Transpose[Tally[Sort[grades, gradeOrder]]];

BarChart[nl, ChartLabels -> gl]


grade chart






share|improve this answer



























    up vote
    1
    down vote













    I had to deal with similar problems many times, and I usually do this with associations.



    We start by defining an exhaustive list of grades in our desired order. I am not that familiar with the American grading system, so I might have gotten some parts of this wrong.



    order = "W", "E-", "E", "E+", "D-", "D", "D+", "C-", "C", "C+", "B-","B", "B+", "A-", "A", "A+";


    We are going to use this to reorder all our datasets. You can produce this list manually or automatically, then re-use it multiple times. In the application that I had, automatic sorting was not possible at all.



    Now create the histogram as an association. We try to always work with associations.



    hist = Counts[grades]
    (* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4,
    "E" -> 4, "D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1,
    "W" -> 2|> *)


    If you only want to keep those grades that actually appear in the dataset, do



    BarChart[KeyTake[hist, order], ChartLabels -> Automatic]


    Mathematica graphics



    If you also want to keep grades whose count is 0,



    BarChart[
    Join[AssociationThread[order, 0], hist],
    ChartLabels -> Automatic
    ]


    Mathematica graphics



    An alternative that is often useful:



    BarChart[
    Lookup[hist, order, 0],
    ChartLabels -> order
    ]


    Mathematica graphics






    share|improve this answer






















      Your Answer




      StackExchange.ifUsing("editor", function ()
      return StackExchange.using("mathjaxEditing", function ()
      StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
      StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
      );
      );
      , "mathjax-editing");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "387"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f182764%2fbetter-way-to-sort-course-grades%23new-answer', 'question_page');

      );

      Post as a guest






























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      2
      down vote













      This is a great use for the Association data structure, which makes so many tasks in Mathematica that much more pleasant.



      First, we can just write out a ranking of grades:



      ranking = "A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", 
      "D", "D-", "E", "W";


      Then we take your grades and count how many of each there are into an association with Counts:



      grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", 
      "B", "C", "B-", "C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B",
      "C+", "B", "C", "B+", "C+", "D-", "C", "A", "E", "B", "B+", "C",
      "C", "D+", "D", "C", "C-", "C", "B", "D", "B", "B", "E", "B", "W",
      "W";

      counts = Counts[grades]
      (* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4, "E" -> 4,
      "D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1, "W" -> 2|> *)


      This is a table associating each grades with its counts, but it's an a useless order. Let's put it in the order you want, using KeyTake, which we can pass directly to BarChart, which can Automaticly figure out the labels:



      ordered = KeyTake[Counts[grades], Reverse@ranking]
      (* <|"W" -> 2, "E" -> 4, "D-" -> 1, "D" -> 3, "D+" -> 2, "C-" -> 4,
      "C" -> 9, "C+" -> 3, "B-" -> 5, "B" -> 11, "B+" -> 3, "A" -> 2|> *)

      BarChart[ordered, ChartLabels -> Automatic]


      bar chart






      share|improve this answer
















      • 1




        Neat use of Association!
        – J. M. is somewhat okay.♦
        25 mins ago






      • 1




        Sorry, I had a stale window that was open for a while, and did not see your answer ...
        – Szabolcs
        15 mins ago










      • @Szabolcs Haha jinx!
        – Pillsy
        10 mins ago















      up vote
      2
      down vote













      This is a great use for the Association data structure, which makes so many tasks in Mathematica that much more pleasant.



      First, we can just write out a ranking of grades:



      ranking = "A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", 
      "D", "D-", "E", "W";


      Then we take your grades and count how many of each there are into an association with Counts:



      grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", 
      "B", "C", "B-", "C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B",
      "C+", "B", "C", "B+", "C+", "D-", "C", "A", "E", "B", "B+", "C",
      "C", "D+", "D", "C", "C-", "C", "B", "D", "B", "B", "E", "B", "W",
      "W";

      counts = Counts[grades]
      (* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4, "E" -> 4,
      "D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1, "W" -> 2|> *)


      This is a table associating each grades with its counts, but it's an a useless order. Let's put it in the order you want, using KeyTake, which we can pass directly to BarChart, which can Automaticly figure out the labels:



      ordered = KeyTake[Counts[grades], Reverse@ranking]
      (* <|"W" -> 2, "E" -> 4, "D-" -> 1, "D" -> 3, "D+" -> 2, "C-" -> 4,
      "C" -> 9, "C+" -> 3, "B-" -> 5, "B" -> 11, "B+" -> 3, "A" -> 2|> *)

      BarChart[ordered, ChartLabels -> Automatic]


      bar chart






      share|improve this answer
















      • 1




        Neat use of Association!
        – J. M. is somewhat okay.♦
        25 mins ago






      • 1




        Sorry, I had a stale window that was open for a while, and did not see your answer ...
        – Szabolcs
        15 mins ago










      • @Szabolcs Haha jinx!
        – Pillsy
        10 mins ago













      up vote
      2
      down vote










      up vote
      2
      down vote









      This is a great use for the Association data structure, which makes so many tasks in Mathematica that much more pleasant.



      First, we can just write out a ranking of grades:



      ranking = "A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", 
      "D", "D-", "E", "W";


      Then we take your grades and count how many of each there are into an association with Counts:



      grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", 
      "B", "C", "B-", "C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B",
      "C+", "B", "C", "B+", "C+", "D-", "C", "A", "E", "B", "B+", "C",
      "C", "D+", "D", "C", "C-", "C", "B", "D", "B", "B", "E", "B", "W",
      "W";

      counts = Counts[grades]
      (* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4, "E" -> 4,
      "D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1, "W" -> 2|> *)


      This is a table associating each grades with its counts, but it's an a useless order. Let's put it in the order you want, using KeyTake, which we can pass directly to BarChart, which can Automaticly figure out the labels:



      ordered = KeyTake[Counts[grades], Reverse@ranking]
      (* <|"W" -> 2, "E" -> 4, "D-" -> 1, "D" -> 3, "D+" -> 2, "C-" -> 4,
      "C" -> 9, "C+" -> 3, "B-" -> 5, "B" -> 11, "B+" -> 3, "A" -> 2|> *)

      BarChart[ordered, ChartLabels -> Automatic]


      bar chart






      share|improve this answer












      This is a great use for the Association data structure, which makes so many tasks in Mathematica that much more pleasant.



      First, we can just write out a ranking of grades:



      ranking = "A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", 
      "D", "D-", "E", "W";


      Then we take your grades and count how many of each there are into an association with Counts:



      grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", 
      "B", "C", "B-", "C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B",
      "C+", "B", "C", "B+", "C+", "D-", "C", "A", "E", "B", "B+", "C",
      "C", "D+", "D", "C", "C-", "C", "B", "D", "B", "B", "E", "B", "W",
      "W";

      counts = Counts[grades]
      (* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4, "E" -> 4,
      "D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1, "W" -> 2|> *)


      This is a table associating each grades with its counts, but it's an a useless order. Let's put it in the order you want, using KeyTake, which we can pass directly to BarChart, which can Automaticly figure out the labels:



      ordered = KeyTake[Counts[grades], Reverse@ranking]
      (* <|"W" -> 2, "E" -> 4, "D-" -> 1, "D" -> 3, "D+" -> 2, "C-" -> 4,
      "C" -> 9, "C+" -> 3, "B-" -> 5, "B" -> 11, "B+" -> 3, "A" -> 2|> *)

      BarChart[ordered, ChartLabels -> Automatic]


      bar chart







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 28 mins ago









      Pillsy

      12.1k13178




      12.1k13178







      • 1




        Neat use of Association!
        – J. M. is somewhat okay.♦
        25 mins ago






      • 1




        Sorry, I had a stale window that was open for a while, and did not see your answer ...
        – Szabolcs
        15 mins ago










      • @Szabolcs Haha jinx!
        – Pillsy
        10 mins ago













      • 1




        Neat use of Association!
        – J. M. is somewhat okay.♦
        25 mins ago






      • 1




        Sorry, I had a stale window that was open for a while, and did not see your answer ...
        – Szabolcs
        15 mins ago










      • @Szabolcs Haha jinx!
        – Pillsy
        10 mins ago








      1




      1




      Neat use of Association!
      – J. M. is somewhat okay.♦
      25 mins ago




      Neat use of Association!
      – J. M. is somewhat okay.♦
      25 mins ago




      1




      1




      Sorry, I had a stale window that was open for a while, and did not see your answer ...
      – Szabolcs
      15 mins ago




      Sorry, I had a stale window that was open for a while, and did not see your answer ...
      – Szabolcs
      15 mins ago












      @Szabolcs Haha jinx!
      – Pillsy
      10 mins ago





      @Szabolcs Haha jinx!
      – Pillsy
      10 mins ago











      up vote
      1
      down vote













      Let's write a custom ordering function that Sort can use:



      gradeOrder[g1_, g2_] := Block[ord,
      ord = -Order[StringTake[g1, 1], StringTake[g2, 1]];
      If[ord != 0, ord,
      Which[StringLength[g1] == 1, 2 Boole[StringMatchQ[g2, "*+"]] - 1,
      StringLength[g2] == 1, 2 Boole[StringMatchQ[g1, "*-"]] - 1,
      True, Order[StringTake[g1, 2], StringTake[g2, 2]]]]]


      With this:



      grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", "B", "C", "B-",
      "C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B", "C+", "B", "C", "B+", "C+",
      "D-", "C", "A", "E", "B", "B+", "C", "C", "D+", "D", "C", "C-", "C", "B", "D",
      "B", "B", "E", "B", "W", "W";


      Then,



      gl, nl = Transpose[Tally[Sort[grades, gradeOrder]]];

      BarChart[nl, ChartLabels -> gl]


      grade chart






      share|improve this answer
























        up vote
        1
        down vote













        Let's write a custom ordering function that Sort can use:



        gradeOrder[g1_, g2_] := Block[ord,
        ord = -Order[StringTake[g1, 1], StringTake[g2, 1]];
        If[ord != 0, ord,
        Which[StringLength[g1] == 1, 2 Boole[StringMatchQ[g2, "*+"]] - 1,
        StringLength[g2] == 1, 2 Boole[StringMatchQ[g1, "*-"]] - 1,
        True, Order[StringTake[g1, 2], StringTake[g2, 2]]]]]


        With this:



        grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", "B", "C", "B-",
        "C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B", "C+", "B", "C", "B+", "C+",
        "D-", "C", "A", "E", "B", "B+", "C", "C", "D+", "D", "C", "C-", "C", "B", "D",
        "B", "B", "E", "B", "W", "W";


        Then,



        gl, nl = Transpose[Tally[Sort[grades, gradeOrder]]];

        BarChart[nl, ChartLabels -> gl]


        grade chart






        share|improve this answer






















          up vote
          1
          down vote










          up vote
          1
          down vote









          Let's write a custom ordering function that Sort can use:



          gradeOrder[g1_, g2_] := Block[ord,
          ord = -Order[StringTake[g1, 1], StringTake[g2, 1]];
          If[ord != 0, ord,
          Which[StringLength[g1] == 1, 2 Boole[StringMatchQ[g2, "*+"]] - 1,
          StringLength[g2] == 1, 2 Boole[StringMatchQ[g1, "*-"]] - 1,
          True, Order[StringTake[g1, 2], StringTake[g2, 2]]]]]


          With this:



          grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", "B", "C", "B-",
          "C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B", "C+", "B", "C", "B+", "C+",
          "D-", "C", "A", "E", "B", "B+", "C", "C", "D+", "D", "C", "C-", "C", "B", "D",
          "B", "B", "E", "B", "W", "W";


          Then,



          gl, nl = Transpose[Tally[Sort[grades, gradeOrder]]];

          BarChart[nl, ChartLabels -> gl]


          grade chart






          share|improve this answer












          Let's write a custom ordering function that Sort can use:



          gradeOrder[g1_, g2_] := Block[ord,
          ord = -Order[StringTake[g1, 1], StringTake[g2, 1]];
          If[ord != 0, ord,
          Which[StringLength[g1] == 1, 2 Boole[StringMatchQ[g2, "*+"]] - 1,
          StringLength[g2] == 1, 2 Boole[StringMatchQ[g1, "*-"]] - 1,
          True, Order[StringTake[g1, 2], StringTake[g2, 2]]]]]


          With this:



          grades = "C", "B-", "B", "B+", "B", "C-", "E", "B", "D", "D+", "C-", "B", "C", "B-",
          "C+", "E", "B-", "B-", "C-", "A", "C", "B-", "B", "C+", "B", "C", "B+", "C+",
          "D-", "C", "A", "E", "B", "B+", "C", "C", "D+", "D", "C", "C-", "C", "B", "D",
          "B", "B", "E", "B", "W", "W";


          Then,



          gl, nl = Transpose[Tally[Sort[grades, gradeOrder]]];

          BarChart[nl, ChartLabels -> gl]


          grade chart







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 30 mins ago









          J. M. is somewhat okay.♦

          93.2k10288445




          93.2k10288445




















              up vote
              1
              down vote













              I had to deal with similar problems many times, and I usually do this with associations.



              We start by defining an exhaustive list of grades in our desired order. I am not that familiar with the American grading system, so I might have gotten some parts of this wrong.



              order = "W", "E-", "E", "E+", "D-", "D", "D+", "C-", "C", "C+", "B-","B", "B+", "A-", "A", "A+";


              We are going to use this to reorder all our datasets. You can produce this list manually or automatically, then re-use it multiple times. In the application that I had, automatic sorting was not possible at all.



              Now create the histogram as an association. We try to always work with associations.



              hist = Counts[grades]
              (* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4,
              "E" -> 4, "D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1,
              "W" -> 2|> *)


              If you only want to keep those grades that actually appear in the dataset, do



              BarChart[KeyTake[hist, order], ChartLabels -> Automatic]


              Mathematica graphics



              If you also want to keep grades whose count is 0,



              BarChart[
              Join[AssociationThread[order, 0], hist],
              ChartLabels -> Automatic
              ]


              Mathematica graphics



              An alternative that is often useful:



              BarChart[
              Lookup[hist, order, 0],
              ChartLabels -> order
              ]


              Mathematica graphics






              share|improve this answer


























                up vote
                1
                down vote













                I had to deal with similar problems many times, and I usually do this with associations.



                We start by defining an exhaustive list of grades in our desired order. I am not that familiar with the American grading system, so I might have gotten some parts of this wrong.



                order = "W", "E-", "E", "E+", "D-", "D", "D+", "C-", "C", "C+", "B-","B", "B+", "A-", "A", "A+";


                We are going to use this to reorder all our datasets. You can produce this list manually or automatically, then re-use it multiple times. In the application that I had, automatic sorting was not possible at all.



                Now create the histogram as an association. We try to always work with associations.



                hist = Counts[grades]
                (* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4,
                "E" -> 4, "D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1,
                "W" -> 2|> *)


                If you only want to keep those grades that actually appear in the dataset, do



                BarChart[KeyTake[hist, order], ChartLabels -> Automatic]


                Mathematica graphics



                If you also want to keep grades whose count is 0,



                BarChart[
                Join[AssociationThread[order, 0], hist],
                ChartLabels -> Automatic
                ]


                Mathematica graphics



                An alternative that is often useful:



                BarChart[
                Lookup[hist, order, 0],
                ChartLabels -> order
                ]


                Mathematica graphics






                share|improve this answer
























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  I had to deal with similar problems many times, and I usually do this with associations.



                  We start by defining an exhaustive list of grades in our desired order. I am not that familiar with the American grading system, so I might have gotten some parts of this wrong.



                  order = "W", "E-", "E", "E+", "D-", "D", "D+", "C-", "C", "C+", "B-","B", "B+", "A-", "A", "A+";


                  We are going to use this to reorder all our datasets. You can produce this list manually or automatically, then re-use it multiple times. In the application that I had, automatic sorting was not possible at all.



                  Now create the histogram as an association. We try to always work with associations.



                  hist = Counts[grades]
                  (* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4,
                  "E" -> 4, "D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1,
                  "W" -> 2|> *)


                  If you only want to keep those grades that actually appear in the dataset, do



                  BarChart[KeyTake[hist, order], ChartLabels -> Automatic]


                  Mathematica graphics



                  If you also want to keep grades whose count is 0,



                  BarChart[
                  Join[AssociationThread[order, 0], hist],
                  ChartLabels -> Automatic
                  ]


                  Mathematica graphics



                  An alternative that is often useful:



                  BarChart[
                  Lookup[hist, order, 0],
                  ChartLabels -> order
                  ]


                  Mathematica graphics






                  share|improve this answer














                  I had to deal with similar problems many times, and I usually do this with associations.



                  We start by defining an exhaustive list of grades in our desired order. I am not that familiar with the American grading system, so I might have gotten some parts of this wrong.



                  order = "W", "E-", "E", "E+", "D-", "D", "D+", "C-", "C", "C+", "B-","B", "B+", "A-", "A", "A+";


                  We are going to use this to reorder all our datasets. You can produce this list manually or automatically, then re-use it multiple times. In the application that I had, automatic sorting was not possible at all.



                  Now create the histogram as an association. We try to always work with associations.



                  hist = Counts[grades]
                  (* <|"C" -> 9, "B-" -> 5, "B" -> 11, "B+" -> 3, "C-" -> 4,
                  "E" -> 4, "D" -> 3, "D+" -> 2, "C+" -> 3, "A" -> 2, "D-" -> 1,
                  "W" -> 2|> *)


                  If you only want to keep those grades that actually appear in the dataset, do



                  BarChart[KeyTake[hist, order], ChartLabels -> Automatic]


                  Mathematica graphics



                  If you also want to keep grades whose count is 0,



                  BarChart[
                  Join[AssociationThread[order, 0], hist],
                  ChartLabels -> Automatic
                  ]


                  Mathematica graphics



                  An alternative that is often useful:



                  BarChart[
                  Lookup[hist, order, 0],
                  ChartLabels -> order
                  ]


                  Mathematica graphics







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 12 mins ago

























                  answered 22 mins ago









                  Szabolcs

                  153k13418902




                  153k13418902



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f182764%2fbetter-way-to-sort-course-grades%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Comments

                      Popular posts from this blog

                      What does second last employer means? [closed]

                      List of Gilmore Girls characters

                      One-line joke