How to Calculate Wind Direction from U and V Wind Components in R

How to calculate wind direction from U and V wind components in R

There are three problems with this:

  1. You cannot convert m/s to radians. In order to input wind components into atan2, you must normalize them, but you don't do this by multiplying m/s by pi/180 (which you did to get u_rad and v_rad). You should make a column of absolute windspeed (sqrt(u_ms^2 + v_ms^2)) and take atan2(u_ms/wind_abs, v_ms/wind_abs). (also note that atan2 takes y component first - make sure that's what you want)
  2. atan2 will give you an answer in the unit circle coordinates, which increase counterclockwise and have a zero on the x-axis. You want an answer in cardinal coordinates which increase clockwise and have a zero on the y-axis. To convert unit circle to cardinal coordinates, you must subtract the unit circle angle from 90.
  3. You must know whether the wind info refers to the direction the wind is coming from (standard for cardinal coordinates) or the direction the wind is blowing (standard for trig/vector operations)

If you are given u_ms = = -3.711 and v_ms = -1.471 (on the unit circle it is blowing down and slightly to the left, so it is coming from the northeast), then:

wind_abs = sqrt(u_ms^2 + v_ms^2)
wind_dir_trig_to = atan2(u_ms/wind_abs, v_ms/wind_abs)
wind_dir_trig_to_degrees = wind_dir_trig_to * 180/pi ## -111.6 degrees

Then you must convert this wind vector to the meteorological convention of the direction the wind is coming from:

wind_dir_trig_from_degrees = wind_dir_trig_to_degrees + 180 ## 68.38 degrees

Then you must convert that angle from "trig" coordinates to cardinal coordinates:

wind_dir_cardinal = 90 - wind_dir_trig_from_degrees
[1] 21.62284 #From the northeast.

Calculating wind direction from U and V components of the wind using lapply or ifelse

First define the function to do the calculation:

windDir <- function(u, v) {
if(v > 0) ((180 / pi) * atan(u/v) + 180)
if(u < 0 & v < 0) ((180 / pi) * atan(u/v) + 0)
if(u > 0 & v < 0) ((180 / pi) * atan(u/v) + 360)
}

Then apply it to each row. Here I'm using ddply, which is a nice "apply" variety for data frames:

> library(plyr)
> ddply(data, 'DateTime', summarize, windDir=windDir(Ucomp, Vcomp))
DateTime windDir
1 1981 278.0232
2 1982 276.0232
3 1983 280.2760
4 1984 277.1531
5 1985 280.0370
6 1986 279.7517

How can I calculate wind direction average in R?

This can be done using the circular package.

To get the mean of 45 and 315 you can use:

library(circular)
mean(circular(c(pi/4,7*pi/4)))
#Circular Data:
#Type = angles
#Units = radians
#Template = none
#Modulo = asis
#Zero = 0
#Rotation = counter
#[1] -1.570092e-16

The reason it isn't exactly 0 is because of floating point precision in R.

To get the mean of wdiryou can use:

mean(circular(wdir, units = "degrees"))
#Circular Data:
#Type = angles
#Units = degrees
#Template = none
#Modulo = asis
#Zero = 0
#Rotation = counter
#[1] 41.05411

Another example:

mean(circular(c(7*pi/2,pi/4, pi/2, 7*pi/2 )))
#Circular Data:
#Type = angles
#Units = radians
#Template = none
#Modulo = asis
#Zero = 0
#Rotation = counter
#[1] -0.3926991

Averaging wind direction in r

It's more of a math question rather than an r question. The thing is that you can't say that mean direction of n vectors equals to the direction of the mean-vector. Consider e.g. two vectors: (1, 0) and (0, 10000). The angle of the first is 0 degrees, the angle of the second is 90 degrees. So, the average direction is 45 degrees. But the mean-vector is (.5, 5000) and it's angle is in fact almost indistinguishable from 90 degrees.

How to implement equation amnog two raster grid cells ( Calculate average wind using u and v wind components on each grid cells)

With RasterStacks vr and ur

vr <- stack(system.file("external/rlogo.grd", package="raster")) 
ur <- flip(vr, 'y')

You can indeed use your formulas:

windir <- atan2(vr, ur) * 180/pi + 180

winav <- (ur^2 + vr^2)^0.5

Alternatively, you can use overlay

windir2 <- overlay(vr, ur, fun=function(x,y) atan2(x,y) *180/pi + 180)

winav2 <- overlay(vr, ur, fun=function(x, y) (x^2 + y^2)^0.5 )

Stick Plot for wind speed and direction data in ggplot

Jon Spring's code works. I'll verify (with slightly different data) and show the output with his code.

Slightly different data, with different WindDir to highlight the diagonals (and 30s):

WindSpeed<-c(1,2,3,5,7,2,3,4,5,6,7,8)
WindDir <- c(0, 30, 45, 60, 90, 120, 135, 150, 180, 225, 270, 315)
TimeStamp<-c("2018-01-02 01:00","2018-01-02 02:00","2018-01-02 03:00","2018-01-02 04:00","2018-01-02 05:00","2018-01-02 06:00","2018-01-02 07:00","2018-01-02 08:00","2018-01-02 09:00","2018-01-02 10:00","2018-01-02 11:00","2018-01-02 12:00")
DF<-data.frame(TimeStamp,WindSpeed, WindDir)
DF$TimeStamp <- as.POSIXct(DF$TimeStamp)

For a little added clarity, I augmented Jon's code for arrow ends, starting points, and color (grouped naïvely).

ggplot(DF) +
geom_segment(aes(x = TimeStamp,
y = 0,
xend = TimeStamp + lubridate::dhours(WindSpeed * 1 * -cos((90-WindDir) / 360 * 2 * pi)),
yend = WindSpeed * 1 * -sin((90-WindDir) / 360 * 2 * pi),
col = factor(TimeStamp)
),
arrow = arrow(length = unit(0.5, "cm")) ) +
geom_point(aes(TimeStamp, 0), size = 1) +
coord_fixed(3600) +
theme(legend.position = "none")

sample wind-dir plot with modified wind direction

I think this clearly shows the 45s as good, specifically the last one hitting the grid lines.

Using your data and this code:

WindSpeed<-c(1,2,3,5,7,2,3,4,5,6,7,8)
WindDir<-c(180,90,320,200,350,10,270,50,9,100,110,129)
TimeStamp<-c("2018-01-02 01:00","2018-01-02 02:00","2018-01-02 03:00","2018-01-02 04:00","2018-01-02 05:00","2018-01-02 06:00","2018-01-02 07:00","2018-01-02 08:00","2018-01-02 09:00","2018-01-02 10:00","2018-01-02 11:00","2018-01-02 12:00")
DF<-data.frame(TimeStamp,WindSpeed, WindDir)
DF$TimeStamp <- as.POSIXct(DF$TimeStamp)

presents:

sample windplot with original data



Related Topics



Leave a reply



Submit