How to calculate wind direction from U and V wind components in R
There are three problems with this:
- 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 bypi/180
(which you did to getu_rad
andv_rad
). You should make a column of absolute windspeed (sqrt(u_ms^2 + v_ms^2)
) and takeatan2(u_ms/wind_abs, v_ms/wind_abs)
. (also note that atan2 takes y component first - make sure that's what you want) 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.- 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 wdir
you 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 RasterStack
s 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")
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:
Related Topics
Putting X-Axis at Top of Ggplot2 Chart
Extract Random Effect Variances from Lme4 Mer Model Object
For Each Group Summarise Means for All Variables in Dataframe (Ddply? Split)
Is There a Function to Add Aov Post-Hoc Testing Results to Ggplot2 Boxplot
Ggplot/Mapping Us Counties - Problems with Visualization Shapes in R
Save All Plots Already Present in the Panel of Rstudio
Any Way to Pause at Specific Frames/Time Points with Transition_Reveal in Gganimate
How to Convert Utm Coordinates to Lat and Long in R
How to Ignore Case When Using Str_Detect
What Is a Neat Command Line Equivalent to Rstudio's Knit HTML
Really Fast Word Ngram Vectorization in R
Dplyr 'Rename' Standard Evaluation Function Not Working as Expected
How to Organize Large Shiny Apps
R: Count Unique Values by Category