# How to average elements of a list based in an interval

Suppose I have a list {x,y} like:

Dados0 = {{21.554, 10.153}, {21.554, 9.23}, {21.554, 11.076}, {27.7141, 8.6141}, {27.7141, 11.4855}, {50.1348, 12.6982}, {50.1348, 14.2854}, {50.1348, 13.4918}, {62.3582, 14.9946}, {62.3582, 14.0375}, {73.7872, 11.324}, {73.7872, 14.0201}, {73.7872, 13.4809}, {91.0558, 17.9158}, {91.0558, 17.6973}, {98.1903, 19.0454}, {98.1903, 20.0584}, {53.0732, 13.4945}, {53.0732, 14.9939}, {53.0732, 10.8706}, {78.118, 11.9695}, {78.118, 13.7522}, {78.118, 11.7149}, {103.903, 15.5091}, {41.7694, 10.9547}, {41.7694, 10.0021}, {41.7694, 11.431}, {47.052, 11.8389}, {47.052, 11.4161}, {58.9521, 13.1612}, {58.9521, 11.8113}, {73.7032, 14.306}, {73.7032, 15.1158}, {83.978, 14.214}, {83.978, 13.9771}, {93.4775, 15.9619}, {93.4775, 17.2388}, {99.097, 16.6628}, {99.097, 16.8635}}

and dx=2.0


How to get another list {X,Y,S} such that {X=Average (x+/-dx),Y=Average of y for the values of x+/-dx, S=standard deviation of Y)?

where x+/-dx means all values of x in the range x-dx and x+dx.

If I use

Dmedia = Dados0 // GroupBy[First] // KeyValueMap[{#1, N@Mean@#2[[All, 2]]}&]


I get a list with the average of y for all equal values of x.

What I need is the average of y for all values of y in x range x-dx to x+dx.

Also, the Standard Deviation of Averaged y as the #3.

For examples, the values {73.7872, 11.324}, {73.7872, 14.0201}, {73.7872, 13.4809}, {73.7032, 14.306}, {73.7032, 15.1158}

will result in {73.7536,13.6494,1.4278}

• Is this what you are looking for? {Around[Mean[data[[All, 1]]], dx], Around[Mean[data[[All, 2]]], dx], StandardDeviation[data[[All, 2]]]} If not, please clarify what you mean by "Average (x+/-dx)". Dec 8, 2021 at 17:50
• x+/-dx means all values of x in the range x-dx and x+dx. I also edit the question with more information. Dec 8, 2021 at 18:36

It is easier to define two auxiliary functions:

select[z_,dx_] := Select[dados0, z - dx < #[[1]] < z + dx &]

average[w_] :=
Flatten[{Mean[w],
If[Length[w] > 1, StandardDeviation[w[[All, 2]] ], 0]} ]


select[ ] finds a sublist that matches your requirements, and average[ ] creates an elmement of the list you are seeking to build - the If[] accounts for sublists of single elements, when it is impossible to evaluate the standard deviation. Solving the problem step by step:

u = select[#, dx] & /@ dados0[[All, 1]]  (* generates the sublists *)
u2 = DeleteDuplicates[u]     (* eliminates duplicates *)
average /@ u2


which can be written in a single line

average /@ DeleteDuplicates[select[#, dx] & /@ dados0[[All, 1]]]


The function "range" gathers all pairs in the list with x values between x-dx and x+dx. The "results" function uses the "range" function to compute the {mean of x, mean of y, and standard deviation of y}

range[data_, x_, dx_] :=
Cases[data, a_ /; (x - dx <= a[[1]] <= x + dx)]

In[11]:= range[data,98,dx]

Out[11]= {{98.1903, 19.0454}, {98.1903, 20.0584}, {99.097,
16.6628}, {99.097, 16.8635}}

results[data_, x_,
dx_] := {Mean[#[[1]]], Mean[#[[2]]], StandardDeviation[#[[2]]]} &@
Transpose[range[data, x, dx]]

In[13]:= results[data,98,dx]

Out[13]= {98.6437, 18.1575, 1.66437}