0

I have a dataset with wind directions at 3-hourly time steps and I would like to calculate daily average wind directions. I am, however, stuck. I got this (with dir = the wind direction in degrees, 0 to 360):

dir = accumarray(ceil((1:numel(dir))/8)',dir(:),[],@mean);

This, however, does not take into account the circular nature of the values. How can I do this? I attach a small sample of the data (year - month - day - hour - wind direction):

2020    4   1   0   77.0016556593828
2020    4   1   3   61.6846224380681
2020    4   1   6   31.4624383596130
2020    4   1   9   35.1994739111645
2020    4   1   12  56.7123189304487
2020    4   1   15  337.212660715222
2020    4   1   18  332.720394142200
2020    4   1   21  359.309990882483
2020    4   2   0   1.81332665386765
2020    4   2   3   316.084846935155
2020    4   2   6   297.362308097189
2020    4   2   9   286.447414863766
2020    4   2   12  253.377128455776
2020    4   2   15  272.755841963236
2020    4   2   18  283.300130880562
2020    4   2   21  305.805458428448
2020    4   3   0   303.435585960465
2020    4   3   3   305.408085546923
2020    4   3   6   314.945219141016
2020    4   3   9   301.363197206495
2020    4   3   12  297.344102342364
2020    4   3   15  294.845524112617
2020    4   3   18  301.544742721005
2020    4   3   21  320.320593041074
user5618251
  • 317
  • 1
  • 9
  • What do you mean by "does not take into account the circular nature of the values"? – BillBokeey Jun 03 '22 at 16:10
  • Just use `accumarray` with the third column as a grouping variable, it should do the trick! – BillBokeey Jun 03 '22 at 16:17
  • Do you mean [this](https://stackoverflow.com/a/491769/2586922)? It should be easy to incorporate into your `accumarray` code (I can't procced any further because I don't see how the variable `dir` relates to the example data) – Luis Mendo Jun 03 '22 at 16:18
  • I mean with that that for example the mean of wind directions of 350 and 10° is calculated to be 180° (what I dont want) instead of 0° (what I want) – Yoni Verhaegen Jun 03 '22 at 16:24
  • @LuisMendo Yes, that is what I mean, the dir variable is the last column of the example data. – Yoni Verhaegen Jun 03 '22 at 16:25
  • @YoniVerhaegen So, is my suggestion enough for you to come up with the solution? If you need more help I will gladly provide an answer, but then you need to clarify how the first input of `accumarray` relates to the example data; they seem unrelated to me – Luis Mendo Jun 03 '22 at 16:37
  • mmm... @Yoni, did you sign in to the wrong account? – beaker Jun 04 '22 at 14:01
  • @beaker huh what do you mean? – Yoni Verhaegen Jun 04 '22 at 18:44
  • @Yoni Well, this question was asked by user5618251, yet you seem to be responding as though you asked the question. I wouldn't mention it except that you've suggested a trivial edit that's taking up space in the review queue that wouldn't have had to be reviewed if user5618251 had made it. – beaker Jun 04 '22 at 19:19

1 Answers1

1

One way to handle the circularity of the data is to use vector addition of the angles. This requires breaking each wind direction angle down into its component vectors.

First convert from degrees to radians (for simplicity)

windDir_rad = deg2rad(windDir_deg);

Then find the projection of the angle onto the x and y axes to get the vector components of the wind direction:

xComponent = cos(winDir_rad);
yComponent = sin(winDir_rad);

You will want to do this for every wind direction on a given day (a simple way is to use a for-loop). Then add up all the x components and all the y components from the 8 wind measurements per day. This will give you a point in cartesian space (i.e. and (x, y) ordered pair). The angle of this point from the origin is one way of interpreting the average wind direction. Simply convert the ordered pair into polar coordinates in order to quickly find what that angle is. Here is an example for how it might work for one day's worth of data:

allXComponents = zeros(1, 8);
allYComponents = zeros(1, 8);
for i = 1:8 %iterate once through for each measurement
xComponent_i = cos(deg2rad(windDirection(index))); %note, you'll have to find a way to index into the correct location in your larger array
yComponent_i = sin(deg2rad(windDirection(index)));

allXComponents(i) = xComponent_i;
allYComponents(i) = yComponent_i;
end

%add up all of the vertical and horizontal components
finalXCoordinate = sum(allXComponents);
finalYCoordinate = sum(allYComponents);

%convert the summed components to polar space
[averageAngle_radians, ~] = cart2pol(finalXCoordinate, finalYCoordinate);

averageAngle_degrees = rad2deg(averageAngle_radians);

Note, there is a single edge case that I can think of, which is when all of your wind directions perfectly cancel out and the final x,y coordinate is (0, 0). In this case, any choice of an average angle is arbitrary.

Since your question seemed more about working with circular data than about indexing your data set correctly in order to get the average of each day, I assume this answer will suffice.

Scott
  • 153
  • 7