# Finding max of a function of the elements in a list of lists

Consider a list of lists of $$m \times n \times 3$$:

{
{{a1, R1, c11}, {a2, R1, c12}, {a3, R1, c13}, ..., {an, R1, c1n}},
{{a1, R2, c21}, {a2, R2, c22}, {a3, R2, c23}, ..., {an, R2, c2n}},
...,
{{a1, Ri, ci1},    ... ,    {aj, Ri, cij}, ..., Null, Null, Null},
...,
{{a1, Rm, cm1}, {a2, Rm, cm2}, {a3, Rm, cm3}, ..., {an, Rm, cmn}}
}


In each 1st-level list, the 2nd element $$R_i$$ is fixed ($$i = 1, 2, ..., m$$ for each row), the 1st element changes from $$a_1$$ to $$a_n$$. Note that the data is produced by calculation and the elements of the 1st-level list may be Null, in this case, the Null should be ignored in the data processing. Here is a minimum sample data.

The question is how to find the maximum of the function $$f=a_jc_{ij}$$ corresponding to each $$R_i$$ in order to plot a curve of $$f_\mathrm{max}$$ vs. $$R_i$$ ? Thank you for any suggestions.

• Try ListPlot[{#[[1, 2]], Max[First[#]*Last[#] & /@ #]} & /@ array], where array is your m by n by 3 list. Sep 2, 2020 at 5:48
• @LouisB there may be Null in my data, straightforward usage of this command has a problem related to this. Please see my update. Sorry for the missing of the key point. Sep 2, 2020 at 7:01
• A simple modification to consider only the lists (ignoring the nulls, etc) would be ListPlot[{#[[1, 2]], Max[First[#]*Last[#] & /@ Cases[#, _List]]} & /@ array] Sep 2, 2020 at 7:12
• @LouisB #[[1, 2]] is used to pick out $R_i$ of each row (1st-level list), so the 1 can be changed to 2, 3, and so on because each sublist in the 1st-level list has the same $R_i$. Right? But when changing it to, say, 2 the command does not work. Why? Sep 2, 2020 at 7:47
• Works for me the symbolic array in the question. Please add your actual data, or a significant sample of if, to your question so everyone can see the problem. Sep 2, 2020 at 7:55

In the following, we define our function f, make-up some data, find the Max of f, and finally plot the “curve” that results.

f=#[[All,1]]*#[[All,3]]&;

SeedRandom[123]
data=Table[{RandomReal[],#,RandomReal[]}&/@Range@5,5]//Transpose;

maxdatalist={#[[All,2]][[1]]&/@#,Max/@f/@#}&@data//Transpose;

ListLinePlot[maxdatalist]


Perhaps this will give you something to work off of? Please, let me know how I can improve it if this works for you?

Edit: If this data has Null contained in it, as the further example will show, one can just remove these elements & use the previous method:

dataWnull={{{0.455719,1,0.977826},{0.0485906,1,0.628267},{0.470198,1,0.40324},{0.562943,1,0.549196},{0.392393,1,0.436287},Null,Null,Null},{{0.943215,2,0.962216},{0.277987,2,0.0902176},{0.971585,2,0.314929},{0.48161,2,0.644256},{0.56848,2,0.482909}},{{0.302348,3,0.466709},{0.876587,3,0.109107},{0.12578,3,0.27226},{0.417551,3,0.704522},{0.160465,3,0.963333},Null,Null},{{0.0616383,4,0.385645},{0.265758,4,0.91861},{0.605748,4,0.671763},{0.961331,4,0.903807},{0.0461463,4,0.496263},Null},{{0.429838,5,0.778744},{0.169916,5,0.0995785},{0.242401,5,0.491803},{0.870494,5,0.631661},{0.495921,5,0.0123512}}};

data2=DeleteCases[Null]/@dataWnull;

maxdata2list={#[[All,2]][[1]]&/@#,Max/@f/@#}&@data2//Transpose;

ListLinePlot[maxdata2list]


Same as above.

• there may be Null in my data, straightforward usage of this command has a problem related to this. Please see my update. Sorry for the missing of the key point. Sep 2, 2020 at 7:11
• @user55777 can you provide the data in an easily copy & paste-able format? I think it should not be discouraged if you put this in plain-text (or within a code-block) as an edit to your question? Simply put, I’m on a mobile device & I can’t copy the data you’ve provided to my Wolfram cloud app. Sep 2, 2020 at 7:22
• @user55777 please see my update. Sep 2, 2020 at 7:40
    First[#].Last[#] & /@
Thread /@ {{{a1, R1, c11}, {a2, R2, c12}, {a3, R3, c13}}, {{a1, R1,
c21}, {a2, R2, c22}, {a3, R3, c33}}}


Need to be updated.

BTW,Where are the data?

Let's start with a symbolic array, like the one in the question

symArray = {
{{a1, R1, c11}, {a2, R1, c12}, {a3, R1, c13}, {an, R1, c1n}},
{{a1, R2, c21}, {a2, R2, c22}, {a3, R2, c23}, {an, R2, c2n}},
{{a1, Ri, ci1},     Null,      {aj, Ri, ci3},     Null, Null, Null},
{{a1, Rm, cm1}, {a2, Rm, cm2}, {a3, Rm, cm3}, {an, Rm, cmn}}};
symArray // MatrixForm;


The maximum products can be calculated from symArray as

Max[First[#]*Last[#] & /@ Cases[#, _List]] & /@ symArray;
% // Column

(*  Max[a1 c11,a2 c12,a3 c13,an c1n]
Max[a1 c21,a2 c22,a3 c23,an c2n]
Max[a1 ci1,aj ci3]
Max[a1 cm1,a2 cm2,a3 cm3,an cmn]   *)


Now do it with a numeric array

SeedRandom[123]
mcols = 3; nrows = 4;
a = RandomInteger[{-10, 10}, nrows];
r = RandomSample[Range[mcols*nrows], nrows] // Sort;
c = RandomReal[{-10, 10}, {mcols, nrows}];
numArray =
Table[{a[[k]], r[[k]], c[[j, k]]}, {k, nrows}, {j, mcols}];
numArray[[2]] = Join[Most[numArray[[2]]], {Null, Null, Null}];
numArray // MatrixForm;

ListLinePlot[{FirstCase[#, x_List :> x[[2]]],
Max[First[#]*Last[#] & /@ Cases[#, _List]]} & /@ numArray]


The FirstCase is used to avoid any Nulls.