R-question: How to linear interpolate using na.approx() for wind directions (angles) 355 and 5 make 0 instead of 180

70 Views Asked by At

I'm trying to linear interpolate a very large dataframe using the na.approx function. Works very well except for angular data e.g. wind directions. If you linear interpolate e.g. 350 and 10 you would get 180 instead of the correct 0 (north direction) Does anybody know a solution for large interpolation

for example:

df <- c(350,NA,10) df <- df %>% na.approx %>% data.frame()

should be 350 0 10 but results are 350 180 10

2

There are 2 best solutions below

1
Jon Spring On BEST ANSWER

This seems closely related to the concept of "circular means," and I think we can use the same approach. Convert your polar coordinate (in this case just an angle, e.g. on the unit circle) to cartesian coordinates, do you interpolation there, and then convert back.

df <- data.frame(theta = c(350, NA, 10))

df |>
  mutate(x_vec = sin(theta*pi/180), # using (x0,y1) for theta = 0
         y_vec = cos(theta*pi/180)) |>
  select(-theta) |>
  zoo::na.approx() |>
  data.frame() |>
  mutate(theta = round(90 - atan2(y_vec, x_vec)/pi*180) %% 360)

Result. Here, theta is our angle: 350, 0, and 10 degrees

          x_vec     y_vec theta
1 -1.736482e-01 0.9848078   350
2 -4.718448e-16 0.9848078     0
3  1.736482e-01 0.9848078    10
2
Carl Witthoft On

The result of "180" is mathematically correct. Unless you find or write a function which "knows" that you are mucking with the degrees in polar coordinates, your wish to return "0" will fail.

A Q&D fix would be to preprocess your input data thusly:

mydata[180 < mydata ] <- mydata[180 < mydata] -360