2

I use the following function to perform a conditional operation on a List:

consider[data_, conditionCOL_, conditionVAL_, listOfCol_] :=
  Select[data, (#[[conditionCOL]] == conditionVAL) &][[All, listOfCol]]

Considering the following example :

dalist = Join[Tuples[Range[4], 2]\[Transpose], {Range[16], Range[17, 32, 1]}
         ]\[Transpose];

enter image description here

I use the following to obtain the means of specific columns defined by the function. This will output the means of entries of column 3 & 4 for which the corresponding entry in column 1 equals 2

Mean@consider[dalist, 1, 2, {3, 4}]

enter image description here

Now, I would like to add constraints/thresholds on the values to be averaged :

Average the values when they are:

  • Above minValue (e.g., 3)
  • Under maxValue (e.g., 25)

Below, an example is given of values the average value of which should be calculated under the above mentioned constraints.

enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
500
  • 6,509
  • 8
  • 46
  • 80
  • 3
    Incidentally, in your initial code, the `Select` statement, alone, returns exactly what your looking for, as `MapThread[{#1, #2}&, ...]` and `Transpose` are exact inverses of each other. – rcollyer Jun 08 '11 at 16:05
  • @rcollyer, Thank You, I adapted it from the follwing, and supressing the #3 I did not think about redundency ! MapThread[Disk[{#1, #2}, #3] &, Transpose@ Partition[ Flatten@Union[ Select[t4dataLAEH10, (#[[9]] == disp) &][[All, 54 ;; 77]]], 3]] – 500 Jun 08 '11 at 16:22
  • suppose you only wanted the first 4 points, i.e. `{conditionCOL, conditionVAL}={1,1}`. What filtered average would you expect from that? There are two ways to interpret it: both columns must meet the filter criteria, which gives an avg of `{4,20}`, or each column is filtered independently which gives an avg of `{4, 37/2}`. The current answers give the former result, while I suspect you wish the latter. – rcollyer Jun 09 '11 at 21:46

2 Answers2

5

Since it is not clear whether you want just to exclude the points outside of the limits from the averaging, or to decide whether or not to perform the averaging, I will address both questions. You can use the following functions to postprocess the results of your consider function (they are rather specific, based on your data format):

filter[data : {{_, _} ..}, {min_, max_}] := 
   Select[data, min < #[[1]] < max && min < #[[2]] < max &]

dataWithinLimitsQ[data : {{_, _} ..}, {min_, max_}] := 
   data == filter[data, {min, max}]

meanFiltered[data : {{_, _} ..}, {min_, max_}] := 
   Mean@filter[data, {min, max}]

Here is how you can use them:

In[365]:= dalist=Join[Tuples[Range[4],2]\[Transpose],{Range[16],Range[17,32,1]}]\[Transpose]
Out[365]= {{1,1,1,17},{1,2,2,18},{1,3,3,19},{1,4,4,20},{2,1,5,21},{2,2,6,22},{2,3,7,23},
{2,4,8,24},{3,1,9,25},{3,2,10,26},{3,3,11,27},{3,4,12,28},{4,1,13,29},{4,2,14,30},{4,3,15,31},
{4,4,16,32}}

In[378]:= considered = consider[dalist,1,1,{3,4}]

Out[378]= {{1,17},{2,18},{3,19},{4,20}}

In[379]:= filter[considered,{2,21}]

Out[379]= {{3,19},{4,20}}

In[380]:= dataWithinLimitsQ[considered,{2,21}]

Out[380]= False

In[381]:= meanFiltered[considered,{2,21}]

Out[381]= {7/2,39/2}
Leonid Shifrin
  • 22,449
  • 4
  • 68
  • 100
2

I would use Cases:

inRange[data_, {min_, max_}] := Cases[data, {__?(min < # < max &)}, 1]

This form also accepts data with an arbitrary number of columns.

dat = {{1, 2, 0}, {6, 7, 4}, {6, 7, 7}, {4, 5, 6}, {4, 5, 3}, {9, 7, 1}, {0, 3, 7}, {6, 2, 1}}

inRange[dat, {2, 7}]

(* Out = {{4, 5, 6}, {4, 5, 3}} *)
Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
  • Unfortunately, the first two columns of the OP's data are filtered by that pattern and it doesn't directly allow different filter ranges for the last two columns. As an alternate pattern, I'd use `{_, _, _?(min1 < # < max1&), _?(min2 < # < max2&)}`. – rcollyer Jun 09 '11 at 21:08
  • @rcollyer my expectation was to use `inRange` _after_ `consider`. Are you suggesting a solution that combines these functions? Also, did 500 ask for a different range for each column? – Mr.Wizard Jun 09 '11 at 21:18
  • there is some ambiguity as to what he actually wanted, as of yet he hasn't responded to my comment, above. My nit was referring to this ambiguity, and was not intended to suggest combining the two operations. Incidentally, Leonid's answer behaves the same way. Also, no he did not ask for a different range for each column, I was just being presumptuous/proactive. – rcollyer Jun 10 '11 at 04:20