Convert wind direction (degrees) into factors in a data.frame

cut is the usual function fur chopping numbers into factors, but the trick is that you need both a vector of breaks, plus the labels for each bin. First, we can grab a table of values from the web with a little scraping:

library(rvest)
library(tidyverse)

url <- 'http://snowfence.umn.edu/Components/winddirectionanddegreeswithouttable3.htm'
page <- read_html(url)
directions_raw <- page %>% html_node('td table') %>% html_table(header = TRUE)

directions <- directions_raw %>% 
    set_names(~tolower(sub(' Direction', '', .x))) %>% 
    slice(-1) %>% 
    separate(degree, c('degree_min', 'degree_max'), sep = '\\s+-\\s+', convert = TRUE)

directions
#>    cardinal degree_min degree_max
#> 1         N     348.75      11.25
#> 2       NNE      11.25      33.75
#> 3        NE      33.75      56.25
#> 4       ENE      56.25      78.75
#> 5         E      78.75     101.25
#> 6       ESE     101.25     123.75
#> 7        SE     123.75     146.25
#> 8       SSE     146.25     168.75
#> 9         S     168.75     191.25
#> 10      SSW     191.25     213.75
#> 11       SW     213.75     236.25
#> 12      WSW     236.25     258.75
#> 13        W     258.75     281.25
#> 14      WNW     281.25     303.75
#> 15       NW     303.75     326.25
#> 16      NNW     326.25     348.75

To make cut work properly, there's an additional complication in that north is a little bit at both the bottom and top of the range (both 0 to 11.25 and 348.75-360), so you'll have to add a bit to the ends of the breaks and labels to make it work right:

wind_dir <- data_frame(
    date = structure(c(13514, 13515, 13516, 13517, 13518, 13519), class = "Date"), 
    SN = c(84084, 84084, 84084, 84084, 84084, 84084), 
    ws = c(21.3, 19.9, 19.3, 21.7, 14.4, 13.9), 
    wd = c(34.8, 37.8, 38.2, 15.1, 359, 355)
)

wind_dir <- wind_dir %>% 
    mutate(wd_cardinal = cut(
        wd, 
        breaks = c(0, directions$degree_max, 360), 
        labels = c(directions$cardinal, 'N')
    ))

wind_dir
#> # A tibble: 6 x 5
#>   date          SN    ws    wd wd_cardinal
#>   <date>     <dbl> <dbl> <dbl> <fct>      
#> 1 2007-01-01 84084  21.3  34.8 NE         
#> 2 2007-01-02 84084  19.9  37.8 NE         
#> 3 2007-01-03 84084  19.3  38.2 NE         
#> 4 2007-01-04 84084  21.7  15.1 NNE        
#> 5 2007-01-05 84084  14.4 359   N          
#> 6 2007-01-06 84084  13.9 355   N
6 Likes