Changing Date Labels From Odd to Even Years - r

I want to make a seemingly trivial adjustment to the chart pictured below:
I would like the labels along the x-axis to be even years, rather than odd years. So instead of going from 2009 -> 2011 -> 2013, they should go from 2008 -> 2010 -> 2012, and so forth...
How do I go about doing this?
Here is the code:
germany_yields <- read.csv(file = "Germany 10-Year Yield Weekly (2007-2020).csv", stringsAsFactors = F)
italy_yields <- read.csv(file = "Italy 10-Year Yield Weekly (2007-2020).csv", stringsAsFactors = F)
germany_yields <- germany_yields[, -(3:6)]
italy_yields <- italy_yields[, -(3:6)]
colnames(germany_yields)[1] <- "Date"
colnames(germany_yields)[2] <- "Germany.Yield"
colnames(italy_yields)[1] <- "Date"
colnames(italy_yields)[2] <- "Italy.Yield"
combined <- join(germany_yields, italy_yields, by = "Date")
combined <- na.omit(combined)
combined$Date <- as.Date(combined$Date,format = "%B %d, %Y")
combined["Spread"] <- combined$Italy.Yield - combined$Germany.Yield
fl_dates <- c(tail(combined$Date, n=1), head(combined$Date, n=1))
ggplot(data=combined, aes(x = Date, y = Spread)) + geom_line() +
scale_x_date(limits = fl_dates,
expand = c(0, 0),
date_breaks = "2 years",
date_labels = "%Y")

A -- not very elegant -- way would be to put these arguments in your scale_x_date() :
scale_x_date(date_labels = "%Y",
breaks = ymd(unique(year(combined$fl_dates)[year(combined$fl_dates)%%2 == 0]), truncated = 2L)
(we define breaks manually, by subsetting the whole range of dates and keeping the even years)

That's actually fairly simple. Just set the lower limit to an even number, and set the upper limit to NA. As you haven't provided a reproducible example, here on some fake data.
library(tidyverse)
mydates <- seq(as.Date("2007/1/1"), by = "3 months", length.out =100)
df <- tibble(
myvalue = rnorm(length(mydates))
)
# without limits argument
ggplot(df ) +
aes(x = mydates, y = myvalue) +
geom_line(size = 1L, colour = "#0c4c8a") +
scale_x_date(date_breaks = "2 years",
date_labels = "%Y")
# with limits argument
ggplot(df ) +
aes(x = mydates, y = myvalue) +
geom_line(size = 1L, colour = "#0c4c8a") +
scale_x_date(date_breaks = "2 years",
date_labels = "%Y",
limits = c(as.Date("2006/1/1"), NA))
Created on 2020-04-29 by the reprex package (v0.3.0)

Related

Reverse datetime axis with custom breaks in ggplot2

Reversing the date order is currently yet not supported in ggplot2, as stated in this GitHub issue. A reverse datetime scale could be created by manually defining a trans function from this answer.
Would be possible to manually define the 1. breaks and 2. labels of datetime axis, just like using the date_breaks and date_labels argument in scale_x_date/scale_y_date function?
Reprex
library(ggplot2)
library(scales)
sample_data = data.frame(
report_date = seq(as.Date("2021-01-01"), as.Date("2021-12-31"), by = "day"),
report_var = seq(1, 365)
)
c_trans <- function(a, b, breaks = b$breaks, format = b$format) {
a <- as.trans(a)
b <- as.trans(b)
name <- paste(a$name, b$name, sep = "-")
trans <- function(x) a$trans(b$trans(x))
inv <- function(x) b$inverse(a$inverse(x))
trans_new(name, trans, inverse = inv, breaks = breaks, format = format)
}
rev_date <- c_trans("reverse", "date")
ggplot(sample_data, aes(x = report_var, y = report_date)) +
geom_point() +
scale_y_continuous(trans = rev_date)
Created on 2021-06-22 by the reprex package (v2.0.0)
Breaks
Manually define a numeric vector in Date class. Add it to the breaks argument of scale_y_continuous function.
scale_y_continuous(
trans = rev_date,
breaks = seq.Date(as.Date("2021-01-01"), as.Date("2021-12-31"), by = "2 weeks")
)
Labels
Create a lambda function that takes the Date input and format the time. Add it to the labels argument of the scale_y_continuous function.
scale_y_continuous(
trans = rev_date,
breaks = seq.Date(as.Date("2021-01-01"), as.Date("2021-12-31"), by = "2 weeks"),
labels = ~ strftime(., "%b %d")
)

ggplot: aggregate multi-year data by Month-Year, aesthetic length error

i've read every relevant aggregate() by month and lubridate question i could find but am still running into an error of aesthetic length. lots didn't work for me bc they grouped data by month but the dataframe only contained data from one year. i don't need the cumulative total of every January across time – i need it to be month- AND year-specific.
my sample data: (df is called "sales")
order_date_create order_sum
2020-05-19 900
2020-08-29 500
2020-08-30 900
2021-02-01 200
2021-02-06 500
aggregating by month-year:
# aggregate by month (i used _moyr short for month year)
sales$bymonth <- aggregate(cbind(order_sum)~month(order_date_create),
data=sales,FUN=sum)
sales$order_moyr <- format(sales$order_date_create, '%m-%Y') # why does this get saved under values instead of data?
here's my ggplot:
# plot
ggplot(sales, aes(order_moyr, order_sum)) +
scale_x_date(limits = c(min, as.Date(now())),
breaks = "1 month",
labels = date_format("%m-%Y")) +
scale_y_continuous(labels = function(x) format(x, big.mark = "'", decimal.mark = ".", scientific = FALSE)) +
labs(x = "Date", y = "Sales Volume", title = "Sales by Month") +
geom_bar(stat="identity")+ theme_economist(base_size = 10, base_family = "sans", horizontal = TRUE, dkpanel = FALSE) + scale_colour_economist()
if i use x = order_date_create and y = order_sum it plots correctly, with month-year axis, but each bar is still daily sum.
if i use x = order_moyr and y = bymonth, i get this error:
Error: Aesthetics must be either length 1 or the same as the data (48839): y
tangentially, if anyone knows how to use both scale::dollar AND format the thousands separator in the same scale_y_continous fcn it would be a great help. i've not found how to do both.
library(scales); library(lubridate); library(dplyr);
library(ggthemes)
sales %>%
count(order_moyr = floor_date(order_date_create, "month"),
wt = order_sum, name = "order_sum") %>%
ggplot(aes(order_moyr, order_sum)) +
scale_x_date(breaks = "1 month",
labels = date_format("%m-%Y")) +
scale_y_continuous(labels = scales::dollar_format(big.mark = "'",
decimal.mark = ".")) +
labs(x = "Date", y = "Sales Volume", title = "Sales by Month") +
geom_bar(stat="identity", width = 25)+
theme_economist(base_size = 10, base_family = "sans",
horizontal = TRUE, dkpanel = FALSE) +
scale_colour_economist()

exclude weekends from x axis in heatmap

I have coded a heatmap using ggplot tiles and it has sequencial days on the x axis . The problem I am trying to solve is to remove weekends from the heatmap and show only weekdays. I have found that one solution would be to transform the dates into factors but if I do that how can I format the labels in scale_x_discrete to be in %d%m date format ? Is there a way to keep the dates as date format instead of turning it into factors ?
Below is an example:
randomString <- function(n=5,length=3) {
randomStringX <- c(1:n)
for(i in 1:n) {
randomStringX[i] <- paste(sample(c(LETTERS),length,replace = TRUE),collapse = "")
}
return(randomStringX)
}
randomString()
data.frame(client=randomString(),day=rep(seq.Date(Sys.Date()-10,length.out=10,by="1 day"),2)) %>% mutate(sales=round(rnorm(20,492,300),1)) %>% mutate(scale=cut(sales,breaks=c(0,100,200,300,max(sales)),labels = c("0-100","100-200","200-300","+300"))) %>% ggplot(.,aes(x=day,y=client,fill=scale)) + geom_tile() + scale_x_date(date_breaks = "1 day")
Thanks in advance
You can exclude data from weekends using the is.weekend function from chron
The weekend dates themselves can be excluded from an x-axis using the bdscale package
library(chron)
library(bdscale)
library(scales)
library(ggplot2)
library(dplyr)
df <- as.data.frame(client = randomString(), day = rep(seq.Date(
Sys.Date() - 10, length.out = 10, by = "1 day"), 2)) %>%
mutate(sales = round(rnorm(20, 492, 300), 1)) %>%
mutate(scale =
cut(
sales,
breaks = c(0, 100, 200, 300, max(sales)),
labels = c("0-100", "100-200", "200-300", "+300")
)) %>%
filter(is.weekend(day) == FALSE)
ggplot(df, aes(x = day, y = client, color = scale, fill = scale)) +
geom_tile() +
# scale_x_date(date_breaks = "1 day") +
theme(axis.text.x = element_text(angle = 45)) +
scale_x_bd(business.dates = sort(df$day), max.major.breaks = 30, labels=scales::date_format('%d %b'))
Removing data from weekends can also be done using lubridate and the wday function as
filter(!wday(day) %in% c(1,7))
Sun/Sat are stored as 1 and 7 respectively. - Credit to #AHart

Plot time series data in r for one year month wise

Need a help plotting in r for time series data.The Y is temperature and X is date(now in format %d-%m-%y) and need a plot like:
temp data in month wise along with a box plot
I have tried:
univariare-temperature
temperature = ts(r$temp, frequency = 12, start = 2011) plot(temperature, xaxt = "n") tsp = attributes(temperature)$tsp dates
= seq(as.Date("2011-01-01"), by = "month", along = temperature) axis(1, at = seq(tsp[1], tsp[2], along = temperature), labels = format(dates, "%m-%y"))
ggplot
gg2=ggplot(r,aes(mnth,temp)) + geom_line()
windows()
print(gg2)
but the format is coming incorrect.
Any help will be really appreciable!!
Thanks
Devi
library(ggplot2)
# Simulated temperature data
temp <- runif(75)
temp.avg <- vector()
x <- 365
for(i in 1:x){
if(i <= round(.33 * x)) {
temp.avg[i] <- mean(sample(temp, 15, replace = TRUE))
} else if (i <= round(.66 * x)) {
temp.avg[i] <- abs(log(mean(sample(temp, 15, replace = TRUE))))
} else {
temp.avg[i] <- mean(sample(temp, 15, replace = TRUE)) * (i / x) + .15
}
}
# Generate sequence of days in Date format "%d-%m-%y"
from <- as.Date("01-1-11 12:00:00 EDT", "%d-%m-%y")
to <- as.Date("31-12-11 12:00:00 EDT", "%d-%m-%y")
times <- seq.Date(from, to, 1)
# Put dates and temperatures into data frame
Temperature_data <- data.frame(date = times, temp = temp.avg)
# Plot in ggplot
ggplot(Temperature_data, aes(date, temp)) +
geom_line() +
ylim(c(0, 1)) +
xlab("") +
ylab("Temperature") +
scale_x_date(date_breaks = "1 month", date_labels = "%b %y") +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
ggtitle("Temperature fluctuations in 2011")

R ggplot2 x-axis not properly show

My question is in the following.
here is my raw data:
type,com,year,month,value
A,CH,2016,1,0
A,CH,2016,2,0
A,CH,2016,3,0
A,CH,2016,4,0
A,CH,2016,5,0
A,CH,2016,6,0
A,CH,2016,7,0
A,CH,2016,8,0
A,CH,2016,9,453128
A,CH,2016,10,868256
A,CH,2016,11,1015080
A,CH,2016,12,650912
B,CH,2016,1,0
B,CH,2016,2,0
B,CH,2016,3,0
B,CH,2016,4,0
B,CH,2016,5,0
B,CH,2016,6,61273
B,CH,2016,7,27711
B,CH,2016,8,161780
B,CH,2016,9,48889
B,CH,2016,10,72805
B,CH,2016,11,131466
B,CH,2016,12,73756
C,CH,2016,1,0
C,CH,2016,2,0
C,CH,2016,3,0
C,CH,2016,4,0
C,CH,2016,5,0
C,CH,2016,6,0
C,CH,2016,7,0
C,CH,2016,8,2200
C,CH,2016,9,111384
C,CH,2016,10,28758
C,CH,2016,11,21161
C,CH,2016,12,0
I use it to plot a line graph with gglot2.
The code is:
test <- read.csv("test.csv", header = T)
test_list <- split(test, test$type)
Rplot <- ggplot(test_list$A, aes(x=month, y=value, col=com))+geom_line()
Rplot
My question:
how to let my x-axis to display like month(1,2,3....,12)?
and how can I combine year and month showing on x-axis at the same time.(Jan2016, Feb2016,.....) or (2016/1, 2016/2,.....)
very appreciate.
Create date_label column as Date class in the dataframe using ymd() from lubridate package.
library( 'lubridate' )
test_list <- lapply( test_list, function( x ) {
x$date_label <- ymd( paste( x$year, month.abb[ x$month ], 01, sep = "-"))
x
})
Manipulate x axis using scale_x_date()
# 1. date_labels = "%Y/%m" - 2016/01
# 2. date_labels = "%m" - 01
# 3. date_labels = "%b %Y" - Jan 2016
library( 'ggplot2' )
ggplot( data = test_list$A, aes( x = date_label, y = value, color = com, group = com ) ) +
geom_line( size = 3 ) +
scale_x_date(name = "month",
date_labels = "%m",
date_breaks = "1 month" )
ggplot( data = test_list$A, aes( x = date_label, y = value, group = com, color = com ) ) +
geom_line( size = 3 ) +
theme( axis.text.x = element_text( angle = 45, hjust = 1 )) +
scale_x_date(name = "month_year",
date_labels = "%b %Y",
date_breaks = "1 month" )
For the first case, you can convert month to be a factor. The following code would eliminate decimals in the month.
test$month <- as.factor(test$month)
test_list <- split(test, test$type)
Rplot <- ggplot(test_list$A, aes(x=month, y=value, col=com, group = 1))+geom_line()
Rplot
To get numeric months you have to have a new column. I will create a new one using dplyr package and change that.
library(dplyr)
# make a new column by joining month after converting it to character and year.
test <- test %>% mutate(exactDate = paste(month.abb[as.numeric(as.character(month))], year, sep=""))
# convert to factor
test$exactDate <- factor(test$exactDate, levels = c("Jan2016","Feb2016","Mar2016","Apr2016","May2016","Jun2016",
"Jul2016","Aug2016","Sep2016", "Oct2016", "Nov2016", "Dec2016"),
labels = c("Jan2016","Feb2016","Mar2016","Apr2016","May2016","Jun2016",
"Jul2016","Aug2016","Sep2016", "Oct2016", "Nov2016", "Dec2016"))
# Plot similarly
test_list <- split(test, test$type)
Rplot <- ggplot(test_list$A, aes(x=exactDate, y=value, col=com, group = 1))+geom_line()
# Rotate axis labels by 90 degrees
Rplot+ theme(axis.text.x=element_text(angle=90, hjust=1))

Resources