Plotting/Mutating Data on R - r

I've trying to plot data that has been mutated into quarterly growth rates from nominal levels.
i.e the original dataset was
Date GDP Level
2010Q1 457
2010Q2 487
2010Q3 538
2010Q4 589
2011Q1 627
2011Q2 672.2
2011Q3 716.4
2011Q4 760.6
2012Q1 804.8
2012Q2 849
2012Q3 893.2
2012Q4 937.4
Which was in an excel file which I have imported using
dataset <- read_excel("xx")
Then, I have done the below in order to mutate it to quarter on quarter growth ("QoQ Growth):
dataset %>%
mutate(QoQ Growth= (GDP Level) / lag(GDP Level, n=1) - 1)
I would like to now plot this % growth across time, however I'm not too sure how what the geom_line code is for a mutated variable, any help would be really truly appreciated! I'm quite new to R and really trying to learn, thanks!

Something like this?
library(tidyverse)
df %>%
mutate(QoQGrowth = (GDPLevel) / lag(GDPLevel, n=1) - 1) %>%
ggplot(aes(factor(Date), QoQGrowth, group=1)) +
geom_line()
Output
Data
df <- structure(list(Date = c("2010Q1", "2010Q2", "2010Q3", "2010Q4",
"2011Q1", "2011Q2", "2011Q3", "2011Q4", "2012Q1", "2012Q2", "2012Q3",
"2012Q4"), GDPLevel = c(457, 487, 538, 589, 627, 672.2, 716.4,
760.6, 804.8, 849, 893.2, 937.4)), class = "data.frame", row.names = c(NA,
-12L))

Package zoo defines a S3 class "yearqtr" and has a function to handle quarterly dates, as.yearqtr. Combined with ggplot2's scale_x_date, the formating of quarterly axis labels becomes easier.
dataset <- read.table(text = "
Date 'GDP Level'
2010Q1 457
2010Q2 487
2010Q3 538
2010Q4 589
2011Q1 627
2011Q2 672.2
2011Q3 716.4
2011Q4 760.6
2012Q1 804.8
2012Q2 849
2012Q3 893.2
2012Q4 937.4
", header = TRUE, check.names = FALSE)
suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(zoo))
library(ggplot2)
dataset %>%
mutate(Date = as.yearqtr(Date, format= "%Y Q%q"),
Date = as.Date(Date)) %>%
mutate(`QoQ Growth` = `GDP Level` / lag(`GDP Level`, n = 1) - 1) %>%
ggplot(aes(Date, `QoQ Growth`)) +
geom_line() +
scale_x_date(date_breaks = "3 months", labels = as.yearqtr) +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1))
#> Warning: Removed 1 row(s) containing missing values (geom_path).
Created on 2022-03-08 by the reprex package (v2.0.1)

Convert dataset to a zoo object z, use diff.zoo to get the growth, QoQ Growth, and then use autoplot.zoo with scale_x_yearqtr.
library(zoo)
library(ggplot2)
z <- read.zoo(dataset, FUN = as.yearqtr)
`QoQ Growth` <- diff(z, arith = FALSE) - 1
autoplot(`QoQ Growth`) +
scale_x_yearqtr(format = "%YQ%q", n = length(`QoQ Growth`)) +
xlab("")

Related

How to build stacked bar chart

How can I build stacked bar chart from this data? Where years will be x axis while OLD and NEW differentiated via colours in bars.
However I want to avoid manual coding and automatize the process.
structure(list(`1998` = c(11, 826), `2000` = c(217, 620), `2007` = c(625,
212), `2012` = c(836, 1)), class = "data.frame", row.names = c("NEW",
"OLD"))
1998 2000 2007 2012
NEW 11 217 625 836
OLD 826 620 212 1
Expected output:
Looking for something like this?
library(tidyverse)
df %>%
# rownames to column
mutate(type = rownames(.)) %>%
# convert to long data
pivot_longer(-"type") %>%
# plot
ggplot() +
geom_col(aes(x = name, y = value, fill = type))

ploting time series with day time in horizontal axis

Hi there I have some working code that selects data from a single station and plots it as a time series.in this data is a date time of the format:
28 11AC068 2018-08-30T02:15:00-06:00
29 11AC068 2018-08-30T02:20:00-06:00
file = "http://dd.weather.gc.ca/hydrometric/csv/SK/hourly/SK_hourly_hydrometric.csv"
skdat <- read.csv(file, head=T, sep=",", dec=".")
skdate <- skdat
colnames(skdat) <- c("ID", "Date", "Water.Level", "Grade.1", "Symbol.1",
"QA/QC-1", "Discharge/Debit", "Grade.2", "Symbol.2",
"QA/QC-2")
#There are 151 Factors of ID
str(skdat$ID)
skdat$Date <- as.Date(skdat$Date, "%h/%m")
#"05AH050","05EF001"#,..: 151 151 151 151 151 151 151 151 151 151 ...
plot.ts(subset(skdat, skdat$ID=='05EF001')$Water.Level, main="Plot TS of ID = 05EF001")
axis.Date(1, at=seq(min(skdat$Date), max(skdat$Date), by="hour"), format="%h-%m")
in the subset the date time is filtered out is there any way to keep that column in the data and use it to plot the horizontal axis just as hour min?
You could try something like this.
library(tidyverse)
file = "http://dd.weather.gc.ca/hydrometric/csv/SK/hourly/SK_hourly_hydrometric.csv"
skdat <- read.csv(file, head=T, sep=",", dec=".", stringsAsFactors = F)
colnames(skdat) <- c("ID", "Date", "Water.Level", "Grade.1", "Symbol.1",
"QA/QC-1", "Discharge/Debit", "Grade.2", "Symbol.2",
"QA/QC-2")
skdat %>% filter(ID=='05EF001') %>%
mutate(Date = gsub("-06:00$", "", Date) %>% lubridate::parse_date_time(., orders = "ymd HMS")) %>%
ggplot(aes(Date, Water.Level))+
geom_line()+
scale_x_datetime(breaks = "4 hours", date_labels = "%H:%M")
Created on 2018-09-01 by the reprex
package (v0.2.0).

How do I group by time in R and plot with ggplot? Can this be done within ggplot?

I'm analysing app data using R and I find myself having to group by time a lot so I can plot it in ggplot, however this doesn't seem easy to do.
my data looks like:
user_id | session_id | timestamp | time_seconds
001 | 123 | 2014-01-01| 251
002 | 845 | 2014-01-01| 514
003 | 741 | 2014-01-02| 141
003 | 477 | 2014-01-03| 221
004 | 121 | 2014-01-03| 120
005 | 921 | 2014-01-04| 60
...
The time_stamp column is formatted with as.Date() so it should be recognised as a date by R.
I need to plot line graphs showing no. of sessions over time in ggplot. Is there a simple way to do this within the ggplot code? for example:
ggplot(df, aes(timestamp,count(session_id)))+
geom_line()
I want to do a count of sessions per date, the above code doesn't work, just an example to show what I'm after.
What I'd also like to do is then summarise by month. I'd also like to look into specific months and would like to subset the data. Can this be done from that line of code? xlim isn't what I'm after as that just "shortens" the axis.
I've tried using the aggregate function but with mixed results, not really what I've been after.
Thanks.
You can use group_by and summarize from the dplyr-package:
library(dplyr)
library(ggplot2)
df %>%
group_by(timestamp) %>%
summarise(session_count = n()) %>%
ggplot(aes(timestamp, session_count)) +
geom_line()
For summarizing the data by month you can do:
df %>%
mutate(month_timestamp = format(timestamp, "%b %Y")) %>%
group_by(month_timestamp) %>%
summarise(session_count = n()) %>%
ggplot(aes(month_timestamp, session_count)) +
geom_line()
The plot here doesn't show something because there's only one month in your data.
Data
df <- structure(list(user_id = c("001", "002", "003", "003", "004", "005"),
session_id = c("123", "845", "741", "477", "121", "921"),
timestamp = structure(c(16071, 16071, 16072, 16073, 16073, 16074),
class = "Date"),
time_seconds = c(251, 514, 141, 221, 120, 60)),
.Names = c("user_id", "session_id", "timestamp", "time_seconds"),
class = c("tbl_df", "tbl", "data.frame"),
row.names = c(NA, -6L))
Might also be convenient to do with lubridate, e.g.
library(tidyverse)
dat <- data.frame(timestamp = rep(seq.Date(as.Date("2014/01/01"), as.Date("2014/12/24"), "day"), each = 2),
sessions = 1)
dat %>%
mutate(month = format(timestamp, "%Y-%m")) %>%
group_by(month) %>%
summarise(sum_session = sum(sessions)) %>%
ggplot(data = e, aes(x = month, y = sum_session, group = 1)) + geom_line()

Start multiple cumulative series from the same point

Let's say I have the following data:
stocks <- structure(list(date = structure(c(15120, 15126, 15156, 15187,
15218, 15250, 15279, 15309, 15342, 15371), class = "Date"), AAPL = c(0,
-0.0349594915528398, 0.163285209696362, -0.0144692603838991,
-0.00912094189637977, 0.0615229895783601, -0.0557834027614259,
0.0596546102691159, 0.127111450820476, 0.188310389721697), LMT = c(0,
0.0394093623514219, -0.064715298915223, -0.0103142125320749,
-0.0208923278478336, 0.0448787708206146, 0.0430164493053814,
0.035188599184363, 0.0175524826908838, 0.0861273642597269)), .Names = c("date",
"AAPL", "LMT"), row.names = c(NA, 10L), class = "data.frame")
Which looks something like that:
date AAPL LMT
1 2011-05-26 0.000000000 0.00000000
2 2011-06-01 -0.034959492 0.03940936
3 2011-07-01 0.163285210 -0.06471530
4 2011-08-01 -0.014469260 -0.01031421
5 2011-09-01 -0.009120942 -0.02089233
6 2011-10-03 0.061522990 0.04487877
7 2011-11-01 -0.055783403 0.04301645
8 2011-12-01 0.059654610 0.03518860
9 2012-01-03 0.127111451 0.01755248
10 2012-02-01 0.188310390 0.08612736
Then I melt it:
library(reshape2)
stocks <- melt(stocks, id.vars = "date")
And then plot it as the cumulative series:
library(ggplot2)
ggplot(stocks, aes(date, cumsum(value), color = variable)) + geom_line()
As you see, the starting points of the series for some reason have different y values (and thus, the graphs do start from different points). The question would be the following: is there any way to make both AAPL and LMT series start from the same (0,0) point?
I would calculate the cumsum value first using dplyr or plyr:
library(dplyr)
stocks %>%
group_by(variable) %>%
mutate(cumsum = cumsum(value)) %>%
ggplot(., aes(x = date, color = variable)) +
geom_line(aes(y = cumsum))

Faceting a Dataset

This is a beginner question. I have spent most of the day trying to work out how to facet my data, but all of the examples of faceting that I have come across seem unsuited to my dataset.
Here are the first five rows from my data:
Date Germany.Yield Italy.Yield Greece.Yield Italy_v_Germany.Spread Greece_v_Germany.Spread
2020-04-19 -0.472 1.820 2.287 2.292 2.759
2020-04-12 -0.472 1.790 2.112 2.262 2.584
2020-04-05 -0.345 1.599 1.829 1.944 2.174
2020-03-29 -0.441 1.542 1.972 1.983 2.413
2020-03-22 -0.475 1.334 1.585 1.809 2.060
I simply want to create two line charts. On both charts the x-axis will be the date. On the first chart, the y-axis should be Italy_v_Germany.Spread and on the second, the y-axis should be Greece_v_Germany.Spread.
The first chart looks like this:
So I want the two charts to appear alongside each other, like this:
The one on the left should be Italy_v_Germany.Spread, and the one on the right should be Greece_v_Germany.Spread.
I really have no idea where to start with this. Hoping that someone can point me in the right direction.
In the interest I making the example reproducible, I will share a link to the CSV files which I'm using: https://1drv.ms/u/s!AvGKDeEV3LOsmmlHkzO6YVQTRiOX?e=mukBVy. Unforunately these files convert into excel format when shared via this link, so you may have to export the files to CSVs so that the code works.
Here is the code that I have so far:
library(ggplot2)
library(scales)
library(extrafont)
library(dplyr)
library(tidyr)
work_dir <- "D:\\OneDrive\\Documents\\Economic Data\\Historical Yields\\Eurozone"
setwd(work_dir)
# Germany
#---------------------------------------
germany_yields <- read.csv(file = "Germany 10-Year Yield Weekly (2007-2020).csv", stringsAsFactors = F)
germany_yields <- germany_yields[, -(3:6)]
colnames(germany_yields)[1] <- "Date"
colnames(germany_yields)[2] <- "Germany.Yield"
#---------------------------------------
# Italy
#---------------------------------------
italy_yields <- read.csv(file = "Italy 10-Year Yield Weekly (2007-2020).csv", stringsAsFactors = F)
italy_yields <- italy_yields[, -(3:6)]
colnames(italy_yields)[1] <- "Date"
colnames(italy_yields)[2] <- "Italy.Yield"
#---------------------------------------
# Greece
#---------------------------------------
greece_yields <- read.csv(file = "Greece 10-Year Yield Weekly (2007-2020).csv", stringsAsFactors = F)
greece_yields <- greece_yields[, -(3:6)]
colnames(greece_yields)[1] <- "Date"
colnames(greece_yields)[2] <- "Greece.Yield"
#---------------------------------------
# Join data
#---------------------------------------
combined <- merge(merge(germany_yields, italy_yields, by = "Date", sort = F),
greece_yields, by = "Date", sort = F)
combined <- na.omit(combined)
combined$Date <- as.Date(combined$Date,format = "%B %d, %Y")
combined["Italy_v_Germany.Spread"] <- combined$Italy.Yield - combined$Germany.Yield
combined["Greece_v_Germany.Spread"] <- combined$Greece.Yield - combined$Germany.Yield
#--------------------------------------------------------------------
fl_dates <- c(tail(combined$Date, n=1), head(combined$Date, n=1))
ggplot(data=combined, aes(x = Date, y = Italy_v_Germany.Spread)) + geom_line() +
scale_x_date(limits = fl_dates,
breaks = seq(as.Date("2008-01-01"), as.Date("2020-01-01"), by="2 years"),
expand = c(0, 0),
date_labels = "%Y")
You need to get your data into a long format, for example, by using pivot_wider. Then it should work.
library(dplyr)
library(tidyr)
library(ggplot2)
data <- tribble(~Date, ~Germany.Yield, ~Italy.Yield, ~Greece.Yield, ~Italy_v_Germany.Spread, ~Greece_v_Germany.Spread,
"2020-04-19", -0.472, 1.820, 2.287, 2.292, 2.759,
"2020-04-19", -0.472, 1.820, 2.287, 2.292, 2.759,
"2020-04-12", -0.472, 1.790, 2.112, 2.262, 2.584,
"2020-04-05", -0.345, 1.599, 1.829, 1.944, 2.174,
"2020-03-29", -0.441, 1.542, 1.972, 1.983, 2.413,
"2020-03-22", -0.475, 1.334, 1.585, 1.809, 2.060
)
data %>%
mutate(Date = as.Date(Date)) %>%
pivot_longer(
cols = ends_with("Spread"),
names_to = "country",
values_to = "Spread_v_Germany",
values_drop_na = TRUE
) %>%
ggplot(., aes(x = Date, y = Spread_v_Germany, group = 1)) +
geom_line() +
facet_wrap(. ~ country)

Resources