4
$\begingroup$

Let's say I have a list of lists like

data={{1,0},{2,1},{2,0},{3,0},{4,0},{5,1},{5,0},{6,0},{7,0},{8,1},{8,0},{9,3},{9,2},{9,1},{9,0},{10,0}};

with varying length and number of columns. It is sorted by a specific column (here by the first column) with applied descending values in another column (here the second column).

What I want to get is a list of lists with only the maximum value of the applied values in column 2 for every single value in column 1 like

result={{1,0},{2,1},{3,0},{4,0},{5,1},{6,0},{7,0},{8,1},{9,3},{10,0}}

With neither Extract[] nor Select[] nor Cases[]did I had any success so far.

The code has to be Mathematica 4.3 compatible, because of why I can't use SelectCasesBy[] nor MaxBy[]..

Sorry if my question is a duplicate. I couldn't find a working solution on your site for my problem so far.

Thanks for your help!

$\endgroup$
3
  • $\begingroup$ Welcome! To make the most of Mma.SE start by taking the tour now. It will help us to help you if you write an excellent question. Edit if improvable, show due diligence, give brief context, include minimal working example of code and data in formatted form**. As you receive give back, vote and answer questions, keep the site useful, be kind, correct mistakes and share what you have learned. $\endgroup$
    – rhermans
    Jul 14, 2017 at 13:31
  • $\begingroup$ There are things to do after your question is answered. It's a good idea to stay vigilant for some time, better approaches may come later improving over previous replies. Experienced users may point alternatives, caveats or limitations. New users should test answers before voting and wait 24 hours before accepting the best one. Participation is essential for the site, please come back to do your part tomorrow $\endgroup$
    – rhermans
    Jul 14, 2017 at 14:12
  • $\begingroup$ ((Merge[Rule @@@ data, Max] // Normal) /. Rule :> List ) == result gives True. $\endgroup$
    – Syed
    Sep 12 at 6:35

2 Answers 2

3
$\begingroup$

Update: Define a function that takes three arguments, a list of data (d) to be processed, a column index (gatherby) by which to gather the data and a column index (maximalby) by which to determine the maximal:

ClearAll[maximalByGatherBy]
maximalByGatherBy[d_, gatherby_, maximalby_] := 
 Sort[#, #1[[maximalby]] >= #2[[maximalby]] &][[1]] & /@ 
 (Select[d, Function[x, x[[gatherby]] == #]] & /@ Union[d[[All, gatherby]]])

Examples:

maximalByGatherBy[data, 1, 2]

{{1, 0}, {2, 1}, {3, 0}, {4, 0}, {5, 1}, {6, 0}, {7, 0}, {8, 1}, {9, 3}, {10, 0}}

maximalByGatherBy[data, 2, 1]

{{10, 0}, {9, 1}, {9, 2}, {9, 3}}

Original answer:

All functions used are available from version 1 onwards:

Sort[#, #1[[-1]] >= #2[[-1]] &][[1]] & /@ 
  (Cases[data, {#, _}] & /@ Union[data[[All, 1]]])

{{1, 0}, {2, 1}, {3, 0}, {4, 0}, {5, 1}, {6, 0}, {7, 0}, {8, 1}, {9, 3}, {10, 0}}

Or

Sort[#, #1[[-1]] >= #2[[-1]] &][[1]] & /@ 
  (Select[data, Function[x, x[[1]] == #]] & /@ Union[data[[All, 1]]])

{{1, 0}, {2, 1}, {3, 0}, {4, 0}, {5, 1}, {6, 0}, {7, 0}, {8, 1}, {9, 3}, {10, 0}}

Alternatively, you can use Ordering (available in Version 4.1) for sorting:

 #[[Ordering[#, -1]]][[1]] & /@ (Cases[data, {#, _}] & /@ Union[data[[All, 1]]]))

{{1, 0}, {2, 1}, {3, 0}, {4, 0}, {5, 1}, {6, 0}, {7, 0}, {8, 1}, {9, 3}, {10, 0}}

$\endgroup$
5
  • $\begingroup$ Brilliant! One can only be grateful of the new functions. Flatten[MaximalBy[Last] /@ GatherBy[data, First], 1] $\endgroup$
    – rhermans
    Jul 14, 2017 at 14:12
  • 1
    $\begingroup$ Thank you @rhemans, Indeed ... How dependent on Gather/ GatherBy we have become:) $\endgroup$
    – kglr
    Jul 14, 2017 at 14:21
  • $\begingroup$ Yes and how frustrating it is without them in older versions of Mathematica... Can't wait to try the different suggestions on monday! Thank you so much, guys! :) $\endgroup$
    – ANewb
    Jul 15, 2017 at 16:59
  • $\begingroup$ @kglr works perfectly! Thank you very much! $\endgroup$
    – ANewb
    Jul 17, 2017 at 8:21
  • $\begingroup$ @andy, my pleasure. Thank you for the accept. $\endgroup$
    – kglr
    Jul 17, 2017 at 13:50
1
$\begingroup$

Since Version 10.1 we can define:

maximalByQuery[dt_] := 
 KeyValueMap[List] @ Query[GroupBy[First -> Last], Max] @ dt

maximalByQuery[dt_, Reverse] :=
 KeyValueMap[{#2, #1} &] @ Query[KeySort @ GroupBy[#, Last -> First, Max] &] @ dt

maximalByQuery[data]

{{1, 0}, {2, 1}, {3, 0}, {4, 0}, {5, 1}, {6, 0}, {7, 0}, {8, 1}, {9, 3}, {10, 0}}

maximalByQuery[data, Reverse]

{{10, 0}, {9, 1}, {9, 2}, {9, 3}}

$\endgroup$

Your Answer

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

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