'ts' object must have one or more observations - r

the error is shown above. I am trying to plot a graph that show the amount of tweet within each month of 2016. My question is how can I am able to found out the amount of tweet for each month in order for me to plot a graph to see which month tweeted the most.
library(ggplot2)
library(RColorBrewer)
library(rstudioapi)
current_path = rstudioapi::getActiveDocumentContext()$path
setwd(dirname(current_path ))
print( getwd() )
donaldtrump <- read.csv("random_poll_tweets.csv", stringsAsFactors = FALSE)
print(str(donaldtrump))
time8_ts <- ts(random$time8, start = c(2016,8), frequency = 12)
time7_ts <- ts(random$time7, start = c(2016,7), frequency = 12)
time6_ts <- ts(random$time6, start = c(2016,6), frequency = 12)
time5_ts <- ts(random$time5, start = c(2016,5), frequency = 12)
time4_ts <- ts(random$time4, start = c(2016,4), frequency = 12)
time3_ts <- ts(random$time3, start = c(2016,3), frequency = 12)
time2_ts <- ts(random$time2, start = c(2016,2), frequency = 12)
time1_ts <- ts(random$time1, start = c(2016,1), frequency = 12)
browser_mts <- cbind(time8_ts, time7_ts,time6_ts,time5_ts,time4_ts,time3_ts,time2_ts,time1_ts)
dimnames(browser_mts)[[2]] <- c("8","7","6","5","4","3","2","1")
pdf(file="fig_browser_tweet_R.pdf",width = 11,height = 8.5)
ts.plot(browser_mts, ylab = "Amount of Tweet", xlab = "Month",
plot.type = "single", col = 1:5)
legend("topright", colnames(browser_mts), col = 1:5, lty = 1, cex=1.75)

library(lubridate)
library(dplyr)
donaldtrump$created_at <- donaldtrump$created_at |>
mdy_hm() |>
floor_date(unit = "month")
donaldtrump |> count(created_at)
Just because you are looking at a time series doesn't mean that you must use a time series object.
If you want a plot:
library(ggplot2)
donaldtrump |>
count(created_at) |>
ggplot(aes(created_at, n)) + geom_col() +
labs(x = "Amount of Tweet", y = "Month")

Related

How to plot multiple xts objects inside list to have n amount of dygraphs printed in an output folder?

I have sample file with csv that describe some stock exchange indexes. I have already managed to:
Create for loop statement to tidy the data in a way that I have those data as DFs in a list.
In each index I calculated using loop OLSSlope, Log values, Percent Change, STDSlope etc.
Create XTS objects that are stored inside list.
I want to write such for loop/ lapply code that will take each xts object inside list, create plot using (dygraph) library and then save this graph in an output file. So that the goal is to have graph for each index that is inside this list of xts objects. I don't have problem with creating one graph for one object but to make it universal inside loop. Code for graph that I want is:
wig20tr_d_xts <- xts(x = wig20tr_d$Zamkniecie,
order.by = wig20tr_d$Date)
wig20tr_d_ols <- xts(x = wig20tr_d$OLSSlope,
order.by = wig20tr_d$Date)
wig20tr_d_stdup <- xts(x = wig20tr_d$OneSTDup,
order.by = wig20tr_d$Date)
wig20tr_d_stduptwo <- xts(x = wig20tr_d$TwoSTDup,
order.by = wig20tr_d$Date)
wig20tr_d_stddown <- xts(x = wig20tr_d$OneSTDdown,
order.by = wig20tr_d$Date)
wig20tr_d_stddowntwo <- xts(x = wig20tr_d$TwoSTDdown,
order.by = wig20tr_d$Date)
wig20 <- cbind(wig20tr_d_xts, wig20tr_d_ols, wig20tr_d_stdup, wig20tr_d_stduptwo, wig20tr_d_stddown, wig20tr_d_stddowntwo)
wig20_graph <- dygraph(wig20, main = "WIG 20 TR", ylab = "Total return in zł") %>%
dySeries("wig20tr_d_xts", color = "black") %>%
dySeries("wig20tr_d_ols", strokeWidth = 2, strokePattern = "dashed", color = "blue") %>%
dySeries("wig20tr_d_stdup", color = "green") %>%
dySeries("wig20tr_d_stduptwo", color = "green") %>%
dySeries("wig20tr_d_stddown", color = "red") %>%
dySeries("wig20tr_d_stddowntwo", color = "red") %>%
dyRangeSelector() %>%
dyUnzoom() %>%
dyOptions(axisLineColor = "navy",
gridLineColor = "lightblue") %>%
dyCrosshair(direction = "vertical")
wig20_graph
htmltools::save_html(wig20_graph, file = "C:/DATA_output/wig20_graph.html")
As you can see I use this addition to the graph:
dyCrosshair <- function(dygraph,
direction = c("both", "horizontal", "vertical")) {
dyPlugin(
dygraph = dygraph,
name = "Crosshair",
path = system.file("plugins/crosshair.js",
package = "dygraphs"),
options = list(direction = match.arg(direction))
)
}
Loop to create list of xts objects is like this:
for(i in 1:length(xts_list)){
df <- xts_list[i]
df <- as.data.frame(df)
colnames(df) <- c("Date", "Zamkniecie", "Trend", "OLSSlope", "LogClose", "LogCloseOLS", "LogCloseOLSSlope", "PercentChange", "LogChange", "OneSTDup", "OneSTDdown", "TwoSTDup", "TwoSTDdown")
time_series <- xts(x = df$Zamkniecie,
order.by = df$Date)
ols <- xts(x = df$OLSSlope,
order.by = df$Date)
stdup <- xts(x = df$OneSTDup,
order.by = df$Date)
stduptwo <- xts(x = df$TwoSTDup,
order.by = df$Date)
stddown <- xts(x = df$OneSTDdown,
order.by = df$Date)
stddowntwo <- xts(x = df$TwoSTDdown,
order.by = df$Date)
time_series_full <- cbind(time_series, ols, stdup, stduptwo, stddown, stddowntwo)
xts_list[[i]] <- time_series_full
print(i)
}
I have problem with adding part with graph inside this last for loop. So that the HTML graph would be named after the index. In this example the index is wig20tr_d

How to fix the error code of object of type 'symbol' is not subsettable

I first started with developing a SMA moving average but I wanted to adapt the function to initiate a stock name from the user
here is my code below
library(quantmod)
library(TTR)
library(PerformanceAnalytics)
stock = readline("Enter the stock name:")
stock
getSymbols(stock, src = 'yahoo', from = '2021-01-01')
barChart(as.name(stock), theme = chartTheme('black'))
# Creating Leading and Lagging Technical Indicators
# a. Simple Moving Average (SMA)
# 1. stock
sma10_stock <- SMA(as.name(stock)$as.name(stock.Close), n = 10)
sma15_stock <- SMA(as.name(stock)$as.name(stock.Close), n = 15)
lineChart(as.name(stock), theme = chartTheme('black'))
addSMA(n = 10, col = 'blue')
addSMA(n = 15, col = 'orange')
legend('left', col = c('green','blue','orange'),
legend = c('stock','SMA10','SMA15'), lty = 1, bty = 'n',
text.col = 'white', cex = 0.8)
# Creating Trading signal with Indicators
# SMA
# a. stock
# SMA 10 Crossover Signal
sma10_stock_ts <- Lag(
ifelse(Lag(Cl(as.name(stock))) < Lag(as.name(stock)) & Cl(as.name(stock)) > sma10_stock,1,
ifelse(Lag(Cl(AMC)) > Lag(sma10_stock) & Cl(AMC) < sma10_stock,-1,0)))
sma10_stock_ts[is.na(sma10_stock_ts)] <- 0
As #MrFlick mentioned you can pass character value of stock in getSymbols with auto.assign = FALSE. To use SMA function you'll not be able to use $stock.Close, you can replace it with column number instead.
library(quantmod)
library(TTR)
library(PerformanceAnalytics)
stock = readline("Enter the stock name:")
data <- getSymbols(stock,src = 'yahoo', from = '2021-01-01', auto.assign = FALSE)
barChart(data, theme = chartTheme('black'))
# Creating Leading and Lagging Technical Indicators
# a. Simple Moving Average (SMA)
# 1. stock
sma10_stock <- SMA(data[, 4], n = 10)
sma15_stock <- SMA(data[, 4], n = 15)
lineChart(data, theme = chartTheme('black'))
addSMA(n = 10, col = 'blue')
addSMA(n = 15, col = 'orange')
legend('left', col = c('green','blue','orange'),
legend = c('stock','SMA10','SMA15'), lty = 1, bty = 'n',
text.col = 'white', cex = 0.8)

How to plot a fringe in zoo object time series to highlight a period?

library(zoo)
dat<-data.frame(
prec<-rnorm(650,mean=300),
temp<-rnorm(650,mean = 22),
pet<-rnorm(650,mean = 79),
bal<-rnorm(650,mean = 225))
colnames(dat)<-c("prec","temp","pet","bal")
dat<-ts(dat,start = c(1965,1),frequency = 12)
plot.zoo(dat)
rect(xleft=1975,xright = 1982,ybottom=0,ytop=800,col= '#FFFF0022',border = "transparent")
rect(xleft=1990,xright = 2000,ybottom=0,ytop=800,col= '#00BFFF22',border = "transparent")
rect(xleft=2010,xright = 2015,ybottom=0,ytop=500,col= '#FF000022',border = "transparent")
But I only get something either out of boundaries or not in the proper x axis This is my result so far
Use a panel function. Also using xblocks can simplify this further:
plot.zoo(dat, panel = function(x, y, ...) {
lines(x, y, ...)
year <- as.integer(x)
xblocks(x, year %in% 1975:1982, col = '#FFFF0022')
xblocks(x, year %in% 1990:2000, col = '#00BFFF22')
xblocks(x, year %in% 2010:2015, col = '#FF000022')
})

I want to plot a line over four bargraphs of data in ggplot using geom_line.

I keep getting an error becasue the bargraphs are used for quaterly data and the line is going to be data from the entire year so it will have many points.
The only issue is with the geom_line function which I am new to using. The error is -->
Error in scale_fill_manual(values = c("green", "yellow")) + geom_line(aes(x = dts2, : non-numeric argument to binary operator
t="DG"
fin=getFinancials(t, auto.assign = F)
dts = labels(fin$BS$A)[[2]]
dts2 = paste(substr(dts,1,7),"::",dts, sep="")
stockprices = getSymbols(t, auto.assign = F)
price = rep(0,NROW(dts))
for(i in 1:NROW(price))
{
price[i]=as.vector(last(stockprices[dts2[i],6]))
}
yr= as.numeric(substr(dts,1,4))
pastyr = yr -2
betayr = paste(pastyr,"::",yr,sep="")
os = fin$BS$A["Total Common Shares Outstanding", ]
gw= fin$BS$A["Goodwill, Net", ]
ta= fin$BS$A["Total Assets", ]
td= fin$BS$A["Total Debt", ]
ni= fin$IS$A["Net Income", ]
btax = fin$IS$A["Income Before Tax", ]
atax = fin$IS$A["Income After Tax",]
intpaid = fin$CF$A["Cash Interest Paid, Supplemental",]
gw[is.na(gw)]=0
intpaid[is.na(intpaid)]=0
taa = (ta - gw)/os
Rd = rep(0,NROW(dts))
for(i in 1:NROW(dts))
{
if(td[i]!=0)
{
Rd[i] = intpaid[i]/td[i]
}
}
gspc = getSymbols("^GSPC", auto.assign = F)
gs5 = getSymbols("GS5", src = "FRED", auto.assign = F)
marketRisk = rep(0,NROW(dts))
riskFree = rep(0,NROW(dts))
beta = rep(0,NROW(dts))
for(i in 1:NROW(dts))
{
marketRisk[i]= mean(yearlyReturn(gspc[betayr[i]]))
riskFree[i] = mean(gs5[betayr[i]])
gspc.weekly = weeklyReturn(gspc[betayr[i]])
stockprices.weekly = weeklyReturn(stockprices[betayr[i]])
beta[i] = CAPM.beta(stockprices.weekly,gspc.weekly)
}
Re = (riskFree/100) + beta * (marketRisk-(riskFree/100))
E = os*price
V=E+td
Tc = (btax - atax)/btax
wacc = (E/V)*Re + (td/V)*Rd*(1-Tc)
margin = (ni/wacc)/os - taa
taadf = data.frame(dts,val = taa,cat="ta")
margindf = data.frame(dts,val = margin ,cat="margin")
mdf=rbind(margindf,taadf)
#linrng = paste(dts[NROW(dts)],"::",dts[1],sep="")
#dfdt = data.frame(stockprices[linrng,6])
#dfdt2 = data.frame(dt = labels(dfdt)[[1]],dfdt$AAPL.Adjusted,cat="taa")
#names(dfdt2)=c("dt,price,cat")
pricedf = data.frame(as.vector((stockprices[dts2[i],6])))
ggplot(mdf, aes(x=dts,y=val,fill=cat)) + geom_bar(stat="identity",color="black")
scale_fill_manual(values = c("green","yellow")) +
geom_line(aes(x=dts2, y=stockprices), stat = "identity",
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE)
Note, the object stockprices is An ‘xts’ object. So, you can't use inside ggplot scale. I picked the fist variable of stockprices object to show the code, but you probabli want another one.
library(dplyr)
library(quantmod)
library(PerformanceAnalytics)
library(ggplot2)
stockprices_df <- as.data.frame(stockprices) %>%
mutate(date = rownames(.)) %>%
filter(date %in% dts)
ggplot() +
geom_col(
data = mdf,
aes(x = dts,y = val,fill = cat)
) +
geom_line(
data = stockprices_df,
aes(x = date, y = DG.Open, group = 1 )
) +
scale_fill_manual(values = c("green","yellow"))
[

Wind rose with ggplot (R)?

I am looking for good R code (or package) that uses ggplot2 to create wind roses that show the frequency, magnitude and direction of winds.
I'm particularly interested in ggplot2 as building the plot that way gives me the chance to leverage the rest of the functionality in there.
Test data
Download a year of weather data from the 80-m level on the National Wind Technology's "M2" tower. This link will create a .csv file that is automatically downloaded. You need to find that file (it's called "20130101.csv"), and read it in.
# read in a data file
data.in <- read.csv(file = "A:/drive/somehwere/20130101.csv",
col.names = c("date","hr","ws.80","wd.80"),
stringsAsFactors = FALSE))
This would work with any .csv file and will overwrite the column names.
Sample data
If you don't want to download that data, here are 10 data points that we will use to demo the process:
data.in <- structure(list(date = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L), .Label = "1/1/2013", class = "factor"), hr = 1:9, ws.80 = c(5,
7, 7, 51.9, 11, 12, 9, 11, 17), wd.80 = c(30, 30, 30, 180, 180,
180, 269, 270, 271)), .Names = c("date", "hr", "ws.80", "wd.80"
), row.names = c(NA, -9L), class = "data.frame")
For sake of argument we'll assume that we are using the data.in data frame, which has two data columns and some kind of date / time information. We'll ignore the date and time information initially.
The ggplot function
I've coded the function below. I'm interested in other people's experience or suggestions on how to improve this.
# WindRose.R
require(ggplot2)
require(RColorBrewer)
plot.windrose <- function(data,
spd,
dir,
spdres = 2,
dirres = 30,
spdmin = 2,
spdmax = 20,
spdseq = NULL,
palette = "YlGnBu",
countmax = NA,
debug = 0){
# Look to see what data was passed in to the function
if (is.numeric(spd) & is.numeric(dir)){
# assume that we've been given vectors of the speed and direction vectors
data <- data.frame(spd = spd,
dir = dir)
spd = "spd"
dir = "dir"
} else if (exists("data")){
# Assume that we've been given a data frame, and the name of the speed
# and direction columns. This is the format we want for later use.
}
# Tidy up input data ----
n.in <- NROW(data)
dnu <- (is.na(data[[spd]]) | is.na(data[[dir]]))
data[[spd]][dnu] <- NA
data[[dir]][dnu] <- NA
# figure out the wind speed bins ----
if (missing(spdseq)){
spdseq <- seq(spdmin,spdmax,spdres)
} else {
if (debug >0){
cat("Using custom speed bins \n")
}
}
# get some information about the number of bins, etc.
n.spd.seq <- length(spdseq)
n.colors.in.range <- n.spd.seq - 1
# create the color map
spd.colors <- colorRampPalette(brewer.pal(min(max(3,
n.colors.in.range),
min(9,
n.colors.in.range)),
palette))(n.colors.in.range)
if (max(data[[spd]],na.rm = TRUE) > spdmax){
spd.breaks <- c(spdseq,
max(data[[spd]],na.rm = TRUE))
spd.labels <- c(paste(c(spdseq[1:n.spd.seq-1]),
'-',
c(spdseq[2:n.spd.seq])),
paste(spdmax,
"-",
max(data[[spd]],na.rm = TRUE)))
spd.colors <- c(spd.colors, "grey50")
} else{
spd.breaks <- spdseq
spd.labels <- paste(c(spdseq[1:n.spd.seq-1]),
'-',
c(spdseq[2:n.spd.seq]))
}
data$spd.binned <- cut(x = data[[spd]],
breaks = spd.breaks,
labels = spd.labels,
ordered_result = TRUE)
# clean up the data
data. <- na.omit(data)
# figure out the wind direction bins
dir.breaks <- c(-dirres/2,
seq(dirres/2, 360-dirres/2, by = dirres),
360+dirres/2)
dir.labels <- c(paste(360-dirres/2,"-",dirres/2),
paste(seq(dirres/2, 360-3*dirres/2, by = dirres),
"-",
seq(3*dirres/2, 360-dirres/2, by = dirres)),
paste(360-dirres/2,"-",dirres/2))
# assign each wind direction to a bin
dir.binned <- cut(data[[dir]],
breaks = dir.breaks,
ordered_result = TRUE)
levels(dir.binned) <- dir.labels
data$dir.binned <- dir.binned
# Run debug if required ----
if (debug>0){
cat(dir.breaks,"\n")
cat(dir.labels,"\n")
cat(levels(dir.binned),"\n")
}
# deal with change in ordering introduced somewhere around version 2.2
if(packageVersion("ggplot2") > "2.2"){
cat("Hadley broke my code\n")
data$spd.binned = with(data, factor(spd.binned, levels = rev(levels(spd.binned))))
spd.colors = rev(spd.colors)
}
# create the plot ----
p.windrose <- ggplot(data = data,
aes(x = dir.binned,
fill = spd.binned)) +
geom_bar() +
scale_x_discrete(drop = FALSE,
labels = waiver()) +
coord_polar(start = -((dirres/2)/360) * 2*pi) +
scale_fill_manual(name = "Wind Speed (m/s)",
values = spd.colors,
drop = FALSE) +
theme(axis.title.x = element_blank())
# adjust axes if required
if (!is.na(countmax)){
p.windrose <- p.windrose +
ylim(c(0,countmax))
}
# print the plot
print(p.windrose)
# return the handle to the wind rose
return(p.windrose)
}
Proof of Concept and Logic
We'll now check that the code does what we expect. For this, we'll use the simple set of demo data.
# try the default settings
p0 <- plot.windrose(spd = data.in$ws.80,
dir = data.in$wd.80)
This gives us this plot:
So: we've correctly binned the data by direction and wind speed, and have coded up our out-of-range data as expected. Looks good!
Using this function
Now we load the real data. We can load this from the URL:
data.in <- read.csv(file = "http://midcdmz.nrel.gov/apps/plot.pl?site=NWTC&start=20010824&edy=26&emo=3&eyr=2062&year=2013&month=1&day=1&endyear=2013&endmonth=12&endday=31&time=0&inst=21&inst=39&type=data&wrlevel=2&preset=0&first=3&math=0&second=-1&value=0.0&user=0&axis=1",
col.names = c("date","hr","ws.80","wd.80"))
or from file:
data.in <- read.csv(file = "A:/blah/20130101.csv",
col.names = c("date","hr","ws.80","wd.80"))
The quick way
The simple way to use this with the M2 data is to just pass in separate vectors for spd and dir (speed and direction):
# try the default settings
p1 <- plot.windrose(spd = data.in$ws.80,
dir = data.in$wd.80)
Which gives us this plot:
And if we want custom bins, we can add those as arguments:
p2 <- plot.windrose(spd = data.in$ws.80,
dir = data.in$wd.80,
spdseq = c(0,3,6,12,20))
Using a data frame and the names of columns
To make the plots more compatible with ggplot(), you can also pass in a data frame and the name of the speed and direction variables:
p.wr2 <- plot.windrose(data = data.in,
spd = "ws.80",
dir = "wd.80")
Faceting by another variable
We can also plot the data by month or year using ggplot's faceting capability. Let's start by getting the time stamp from the date and hour information in data.in, and converting to month and year:
# first create a true POSIXCT timestamp from the date and hour columns
data.in$timestamp <- as.POSIXct(paste0(data.in$date, " ", data.in$hr),
tz = "GMT",
format = "%m/%d/%Y %H:%M")
# Convert the time stamp to years and months
data.in$Year <- as.numeric(format(data.in$timestamp, "%Y"))
data.in$month <- factor(format(data.in$timestamp, "%B"),
levels = month.name)
Then you can apply faceting to show how the wind rose varies by month:
# recreate p.wr2, so that includes the new data
p.wr2 <- plot.windrose(data = data.in,
spd = "ws.80",
dir = "wd.80")
# now generate the faceting
p.wr3 <- p.wr2 + facet_wrap(~month,
ncol = 3)
# and remove labels for clarity
p.wr3 <- p.wr3 + theme(axis.text.x = element_blank(),
axis.title.x = element_blank())
Comments
Some things to note about the function and how it can be used:
The inputs are:
vectors of speed (spd) and direction (dir) or the name of the data frame and the names of the columns that contain the speed and direction data.
optional values of the bin size for wind speed (spdres) and direction (dirres).
palette is the name of a colorbrewer sequential palette,
countmax sets the range of the wind rose.
debug is a switch (0,1,2) to enable different levels of debugging.
I wanted to be able to set the maximum speed (spdmax) and the count (countmax) for the plots so that I can compare windroses from different data sets
If there are wind speeds that exceed (spdmax), those are added as a grey region (see the figure). I should probably code something like spdmin as well, and color-code regions where the wind speeds are less than that.
Following a request, I implemented a method to use custom wind speed bins. They can be added using the spdseq = c(1,3,5,12) argument.
You can remove the degree bin labels using the usual ggplot commands to clear the x axis: p.wr3 + theme(axis.text.x = element_blank(),axis.title.x = element_blank()).
At some point recently ggplot2 changed the ordering of bins, so that the plots didn't work. I think this was version 2.2. But, if your plots look a bit weird, change the code so that test for "2.2" is maybe "2.1", or "2.0".
Here is my version of the code. I added labels for directions (N, NNE, NE, ENE, E....) and made the y label to show frequency in percent instead of counts.
Click here to see figure of wind Rose with directions and frequency (%)
# WindRose.R
require(ggplot2)
require(RColorBrewer)
require(scales)
plot.windrose <- function(data,
spd,
dir,
spdres = 2,
dirres = 22.5,
spdmin = 2,
spdmax = 20,
spdseq = NULL,
palette = "YlGnBu",
countmax = NA,
debug = 0){
# Look to see what data was passed in to the function
if (is.numeric(spd) & is.numeric(dir)){
# assume that we've been given vectors of the speed and direction vectors
data <- data.frame(spd = spd,
dir = dir)
spd = "spd"
dir = "dir"
} else if (exists("data")){
# Assume that we've been given a data frame, and the name of the speed
# and direction columns. This is the format we want for later use.
}
# Tidy up input data ----
n.in <- NROW(data)
dnu <- (is.na(data[[spd]]) | is.na(data[[dir]]))
data[[spd]][dnu] <- NA
data[[dir]][dnu] <- NA
# figure out the wind speed bins ----
if (missing(spdseq)){
spdseq <- seq(spdmin,spdmax,spdres)
} else {
if (debug >0){
cat("Using custom speed bins \n")
}
}
# get some information about the number of bins, etc.
n.spd.seq <- length(spdseq)
n.colors.in.range <- n.spd.seq - 1
# create the color map
spd.colors <- colorRampPalette(brewer.pal(min(max(3,
n.colors.in.range),
min(9,
n.colors.in.range)),
palette))(n.colors.in.range)
if (max(data[[spd]],na.rm = TRUE) > spdmax){
spd.breaks <- c(spdseq,
max(data[[spd]],na.rm = TRUE))
spd.labels <- c(paste(c(spdseq[1:n.spd.seq-1]),
'-',
c(spdseq[2:n.spd.seq])),
paste(spdmax,
"-",
max(data[[spd]],na.rm = TRUE)))
spd.colors <- c(spd.colors, "grey50")
} else{
spd.breaks <- spdseq
spd.labels <- paste(c(spdseq[1:n.spd.seq-1]),
'-',
c(spdseq[2:n.spd.seq]))
}
data$spd.binned <- cut(x = data[[spd]],
breaks = spd.breaks,
labels = spd.labels,
ordered_result = TRUE)
# figure out the wind direction bins
dir.breaks <- c(-dirres/2,
seq(dirres/2, 360-dirres/2, by = dirres),
360+dirres/2)
dir.labels <- c(paste(360-dirres/2,"-",dirres/2),
paste(seq(dirres/2, 360-3*dirres/2, by = dirres),
"-",
seq(3*dirres/2, 360-dirres/2, by = dirres)),
paste(360-dirres/2,"-",dirres/2))
# assign each wind direction to a bin
dir.binned <- cut(data[[dir]],
breaks = dir.breaks,
ordered_result = TRUE)
levels(dir.binned) <- dir.labels
data$dir.binned <- dir.binned
# Run debug if required ----
if (debug>0){
cat(dir.breaks,"\n")
cat(dir.labels,"\n")
cat(levels(dir.binned),"\n")
}
# create the plot ----
p.windrose <- ggplot(data = data,
aes(x = dir.binned,
fill = spd.binned
,y = (..count..)/sum(..count..)
))+
geom_bar() +
scale_x_discrete(drop = FALSE,
labels = c("N","NNE","NE","ENE", "E",
"ESE", "SE","SSE",
"S","SSW", "SW","WSW", "W",
"WNW","NW","NNW")) +
coord_polar(start = -((dirres/2)/360) * 2*pi) +
scale_fill_manual(name = "Wind Speed (m/s)",
values = spd.colors,
drop = FALSE) +
theme(axis.title.x = element_blank()) +
scale_y_continuous(labels = percent) +
ylab("Frequencia")
# adjust axes if required
if (!is.na(countmax)){
p.windrose <- p.windrose +
ylim(c(0,countmax))
}
# print the plot
print(p.windrose)
# return the handle to the wind rose
return(p.windrose)
}
Have you ever tried windRose function from Openair package? It's very easy and you can set intervals, statistics and etc.
windRose(mydata, ws = "ws", wd = "wd", ws2 = NA, wd2 = NA,
ws.int = 2, angle = 30, type = "default", bias.corr = TRUE, cols
= "default", grid.line = NULL, width = 1, seg = NULL, auto.text
= TRUE, breaks = 4, offset = 10, normalise = FALSE, max.freq =
NULL, paddle = TRUE, key.header = NULL, key.footer = "(m/s)",
key.position = "bottom", key = TRUE, dig.lab = 5, statistic =
"prop.count", pollutant = NULL, annotate = TRUE, angle.scale =
315, border = NA, ...)
pollutionRose(mydata, pollutant = "nox", key.footer = pollutant,
key.position = "right", key = TRUE, breaks = 6, paddle = FALSE,
seg = 0.9, normalise = FALSE, ...)

Resources