Add secondary axis as a line chart to DY graphs in R - r

I was able to get the bar plots with the below code. However I am trying to add secondary axis to Semi-Final column as a line chart. Can we add this ?
mobility_aus_sum <- structure(list(Year = c(2020, 2020, 2020, 2020, 2020, 2020, 2020,
2020, 2020, 2020, 2020, 2021, 2021, 2021, 2021, 2021, 2021, 2021,
2021, 2021, 2021, 2021, 2021, 2022, 2022), mon_day = c("April",
"August", "December", "February", "July", "June", "March", "May",
"November", "October", "September", "April", "August", "December",
"February", "January", "July", "June", "March", "May", "November",
"October", "September", "February", "January"), Final = c(-1483,
-912, -405, -232, -698, -739, -633, -1125, -540, -738, -802,
-482, -1012, -260, -607, -677, -827, -549, -509, -440, -326,
-659, -871, -480, -639), `Semi-Final` = c(-1333, -762, -255,
-82, -548, -589, -483, -975, -390, -588, -652, -332, -862, -110,
-457, -527, -677, -399, -359, -290, -176, -509, -721, -330, -489
)), row.names = c(NA, -25L), groups = structure(list(Year = c(2020,
2021, 2022), .rows = structure(list(1:11, 12:23, 24:25), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), row.names = c(NA, 3L), class = c("tbl_df",
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
dates <- with(mobility_aus_sum, as.Date(paste(Year, mon_day, 1), "%Y %B %d"))
df2 <- mobility_aus_sum[order(dates),]
df3 <- ts(df2$Final, start = c(df2$Year[1], match(df2$mon_day[1], month.name)),
frequency = 12)
dygraph(df3) %>%
dyRangeSelector() %>%
dyBarChart()

You may try(You need to download barseries.js)
library(dplyr)
library(dygraphs)
library(tibble)
dyBarSeries <- function(dygraph, name, ...) {
file <- "D:/barseries.js" #you need to link to the downloaded file
plotter_ <- paste0(readLines(file, skipNul = T), collapse = "\n")
dots <- list(...)
do.call('dySeries', c(list(dygraph = dygraph, name = name, plotter =
plotter_), dots))
}
mobility_aus_sum %>%
mutate(mon_day = match(mon_day, month.name)) %>%
rowwise %>%
mutate(dates = paste0(c(Year, mon_day, 1), collapse = "-")) %>%
mutate(dates = as.Date(dates, "%Y-%m-%d")) %>%
ungroup %>%
select(-mon_day, -Year) %>%
column_to_rownames(var = 'dates') %>%
dygraph(.) %>%
dyAxis("y", label = "Final", valueRange = c(-1500, -200), independentTicks = TRUE) %>%
dyAxis("y2", label = "Semi-Final ", valueRange = c(-1400, 0), independentTicks = TRUE) %>%
dyBarSeries("Final") %>%
dySeries("Semi-Final", axis=('y2')) %>%
dyRangeSelector()

Related

Plot temperature over time (date)

I am trying to plot temperature over time (in the form of a date), however, I am not sure how to.
See here my original table in Excel:
Or as R code:
dput(Average_temperature_period)
structure(list(Sample = c("ZS_IG_1", "AK_SN_1", "JP_IG_2", "AW_IG_1",
"SBB_SN_1", "AW_IG_2", "JvH_IG_3", "JvH_IG_2", "SBB_SN_4", "SBB_SN_3",
"SBB_SN_2", "EF_SN_1", "JP_IG_2", "JvH_IG_3", "EF_SN_1", "JvH_IG_2",
"AK_SN_1", "ZS_IG_1", "AW_IG_1", "SBB_SN_1", "AW_IG_2", "SBB_SN_4",
"SBB_SN_3", "SBB_SN_2"), Sampling_date = c("23/03/2022", "24/03/2022",
"25/03/2022", "25/03/2022", "25/03/2022", "25/03/2022", "29/03/2022",
"29/03/2022", "01/04/2022", "01/04/2022", "01/04/2022", "12/04/2022",
"25/04/2022", "26/04/2022", "28/04/2022", "29/04/2022", "03/05/2022",
"04/05/2022", "10/05/2022", "10/05/2022", "11/05/2022", "11/05/2022",
"12/05/2022", "12/05/2022"), Period = c("March", "March", "March",
"March", "March", "March", "March", "March", "March", "March",
"March", "March", "AprilMay", "AprilMay", "AprilMay", "AprilMay",
"AprilMay", "AprilMay", "AprilMay", "AprilMay", "AprilMay", "AprilMay",
"AprilMay", "AprilMay"), Average_temperature_field = c(7.137037037,
6.966666667, 10.55555556, 7.281481481, 6.874074074, 9.211111111,
9.662962963, 8.12962963, 6.707407407, 6.774074074, 7.162962963,
8.114814815, NA, 11.74814815, 13.51111111, 11.29259259, 15.4962963,
NA, 15.45925926, 17.14814815, 17.72592593, 15.84074074, 16.85555556,
19.78148148), Average_moisture_field = c(33.48518519, 47.35555556,
32.54814815, 34.01851852, 38.66666667, 31.71851852, 23.54814815,
26.83333333, 42.47777778, 29.45555556, 44.50740741, 40.27407407,
25.77407407, 18.91481481, 26.67777778, 16.27407407, 25.38518519,
19.9962963, 18.27777778, 16.14074074, 22.86666667, 23.48518519,
13.93703704, 20.92222222)), row.names = c(NA, 24L), class = "data.frame")
See here my code in R thus far:
##### Soil temperature graph
Average_temperature_period <- read.csv("~/Desktop/First Internship/MicroResp/R/R script/Average_temperature_period.csv")
Average_temperature_period$Sampling_date <- as.character(Average_temperature_period$Sampling_date)
Average_temperature_period <- Average_temperature_period[c(1:24),c(1:5)]
# Change order x axis (past to present)
Average_temperature_period$Sampling_date <- factor(Average_temperature_period$Sampling_date, levels = c("23/03/22","24/03/22","25/03/22","29/03/22","01/04/22","12/04/22","25/04/22","26/04/22","28/04/22","29/04/22","03/05/22","04/05/22","10/05/22","11/05/22","12/05/22"))
# Plot average temperature against the date
ggplot(data=Average_temperature_period, aes(x=Sampling_date, y=Average_temperature_field)) +
geom_smooth(method = "lm", se=FALSE, color="black", aes(group=1)) +
theme_classic() +
ylab("Average soil temperature (°C)") +
xlab("Sampling date")
The x axis keeps on showing 'NA' for the sampling date. Does anyone know why and how to fix it? I would like to have the x axis in order of date (past to present).
Update with the new data and request of OP:
adding this line drop_na(Average_temperature_field) %>%
library(tidyverse)
library(lubridate)
df %>%
drop_na(Average_temperature_field) %>%
mutate(Sampling_date = dmy(Sampling_date)) %>%
group_by(Sampling_date) %>%
summarise(avg_temp_day = mean(Average_temperature_field,na.rm = TRUE)) %>%
ggplot(aes(x = Sampling_date, y=avg_temp_day))+
geom_point()+
geom_line()+
scale_x_date(date_labels="%d %b",date_breaks ="1 day")+
theme_bw()+
theme(axis.text.x = element_text(angle = 45, vjust = 0.5, hjust=1))
First answer:
Here is one way to do it. You have sometimes two temperatures per day so I used the mean for this day:
library(tidyverse)
library(lubridate)
df %>%
mutate(Sampling_date = dmy(Sampling_date)) %>%
group_by(Sampling_date) %>%
summarise(avg_temp_day = mean(Average_temperature_field,na.rm = TRUE)) %>%
ggplot(aes(x = Sampling_date, y=avg_temp_day))+
geom_point()+
geom_line()+
scale_x_date(date_labels="%d %b",date_breaks ="2 day")+
theme_bw()+
theme(axis.text.x = element_text(angle = 45, vjust = 0.5, hjust=1))
data:
df <- structure(list(Sample = c("ZS_IG_1", "AK_SN_1", "JP_IG_2", "AW_IG_1",
"SBB_SN_1", "AW_IG_2", "JvH_IG_3", "JvH_IG_2", "SBB_SN_4", "SBB_SN_3",
"SBB_SN_2", "EF_SN_1", "JP_IG_2", "JvH_IG_3", "EF_SN_1", "JvH_IG_2",
"AK_SN_1", "ZS_IG_1", "AW_IG_1", "SBB_SN_1", "AW_IG_2", "SBB_SN_4",
"SBB_SN_3", "SBB_SN_2"), Sampling_date = c("23/03/2022", "24/03/2022",
"25/03/2022", "25/03/2022", "25/03/2022", "25/03/2022", "29/03/2022",
"29/03/2022", "01/04/2022", "01/04/2022", "01/04/2022", "12/04/2022",
"25/04/2022", "26/04/2022", "28/04/2022", "29/04/2022", "03/05/2022",
"04/05/2022", "10/05/2022", "10/05/2022", "11/05/2022", "11/05/2022",
"12/05/2022", "12/05/2022"), Period = c("March", "March", "March",
"March", "March", "March", "March", "March", "March", "March",
"March", "March", "AprilMay", "AprilMay", "AprilMay", "AprilMay",
"AprilMay", "AprilMay", "AprilMay", "AprilMay", "AprilMay", "AprilMay",
"AprilMay", "AprilMay"), Average_temperature_field = c(33.48518519,
47.35555556, 32.54814815, 34.01851852, 38.66666667, 31.71851852,
23.54814815, 26.83333333, 42.47777778, 29.45555556, 44.50740741,
40.27407407, 25.77407407, 11.74814815, 13.51111111, 11.29259259,
15.4962963, 19.9962963, 15.45925926, 17.14814815, 17.72592593,
15.84074074, 16.85555556, 19.78148148), Average_moisture_field = c(7.137037037,
6.966666667, 10.55555556, 7.281481481, 6.874074074, 9.211111111,
9.662962963, 8.12962963, 6.707407407, 6.774074074, 7.162962963,
8.114814815, NA, 18.91481481, 26.67777778, 16.27407407, 25.38518519,
NA, 18.27777778, 16.14074074, 22.86666667, 23.48518519, 13.93703704,
20.92222222)), class = "data.frame", row.names = c(NA, -24L))

ggplot boxplot with custom X-Axis and grouping and sorting on separate values

I'm trying to create a boxplot based on timeseries data for multiple years. I want to group observations from multiple years by a variable "DAP" (similar to day of year 0-365), order them by day from November to March but only display the Month on the X-Axis.
I can create a custom order and X-Axis by creating a factor with each month, that works
level_order <- c('November', 'December', 'January', 'February', 'March')
plot <- ggplot(data = df, aes(y = y, x = factor(Month,level = level_order), group=DAP)) +
geom_boxplot(fill="grey85", width = 2.0) +
scale_x_discrete(limits = level_order)
plot
Now I'm stuck making the alignment on the X-Axis according to the days of the month. For example the first datapoint from November 26th needs to more right, closer to December.
Changing the X-Axis to "Date" creates monthly labels for each year and also removed the grouping.
plot <- ggplot(data = df, aes(y = y, x = Date, group=DAP)) +
geom_boxplot(fill="grey85")
plot + scale_x_date(date_breaks = "1 month", date_labels = "%B")
Setting the X-Axis to "DAP" instead of date gives me the correct order and spacing , but I need to display month on the X-Axis. How can I combine this last graph with the X-Axis labeling of graph 1?
plot <- ggplot(data = df, aes(y = y, x = DAP, group=DAP)) +
geom_boxplot(fill="grey85")
plot
and here a sample of the dataset
DAP Date Month y
1 47 2010-11-26 November 0.6872708
21 116 2011-02-03 February 0.7643213
41 68 2011-12-17 December 0.7021531
61 137 2012-02-24 February 0.7178306
81 92 2013-01-10 January 0.7330749
101 44 2013-11-23 November 0.6610618
121 113 2014-01-31 January 0.7961012
141 68 2014-12-17 December 0.7510821
161 137 2015-02-24 February 0.7799938
181 92 2016-01-10 January 0.6861423
201 47 2016-11-26 November 0.7155526
221 116 2017-02-03 February 0.7397810
241 72 2017-12-21 December 0.7259670
261 144 2018-03-03 March 0.6725775
281 106 2019-01-24 January 0.7637322
301 65 2019-12-14 December 0.7184616
321 134 2020-02-21 February 0.6760159
The following approach uses tidyverse. The date is separated into year-month-day and those newly created columns are made numeric. In the ggplot part position_dodge2(preserve = "single") is used which keeps the boxwidth the same. scale_x_discrete helps to redefine x-axis breaks and tick labels. width = 1 controls the distance between the boxes.
library(tidyverse)
df <- tibble::tribble(
~DAP, ~Date, ~Month, ~y,
47, "2010-11-26", "November", 0.6872708,
116, "2011-02-03", "February", 0.7643213,
68, "2011-12-17", "December", 0.7021531,
137, "2012-02-24", "February", 0.7178306,
92, "2013-01-10", "January", 0.7330749,
44, "2013-11-23", "November", 0.6610618,
113, "2014-01-31", "January", 0.7961012,
68, "2014-12-17", "December", 0.7510821,
137, "2015-02-24", "February", 0.7799938,
92, "2016-01-10", "January", 0.6861423,
47, "2016-11-26", "November", 0.7155526,
116, "2017-02-03", "February", 0.7397810,
72, "2017-12-21", "December", 0.7259670,
144, "2018-03-03", "March", 0.6725775,
106, "2019-01-24", "January", 0.7637322,
65, "2019-12-14", "December", 0.7184616,
134, "2020-02-21", "February", 0.6760159
)
df$Date <- as.Date(df$Date)
df %>%
separate(Date, sep = "-", into = c("year", "month", "day")) %>%
mutate_at(vars("year":"day"), as.numeric) %>%
select(-c(year, Month)) %>%
ggplot(aes(
x = factor(month, level = c(11, 12, 1, 2, 3)), y = y,
group = DAP, color = factor(month)
)) +
geom_boxplot(width = 1, lwd = 0.2, position = position_dodge2(preserve = "single")) +
scale_x_discrete(
breaks = c(11, 12, 1, 2, 3),
labels = c("November", "December", "January", "February", "March")
) +
labs(x = "") +
theme(legend.position = "none")
Try this. To get the right order, spacing and labels I make a new date. As year seems to be not relevant I set the year for obs November and December to 2019,
and for the other obs to 2020.
df <- structure(list(DAP = c(
47L, 116L, 68L, 137L, 92L, 44L, 113L,
68L, 137L, 92L, 47L, 116L, 72L, 144L, 106L, 65L, 134L
), Date = c(
"2010-11-26",
"2011-02-03", "2011-12-17", "2012-02-24", "2013-01-10", "2013-11-23",
"2014-01-31", "2014-12-17", "2015-02-24", "2016-01-10", "2016-11-26",
"2017-02-03", "2017-12-21", "2018-03-03", "2019-01-24", "2019-12-14",
"2020-02-21"
), Month = c(
"November", "February", "December",
"February", "January", "November", "January", "December", "February",
"January", "November", "February", "December", "March", "January",
"December", "February"
), y = c(
0.6872708, 0.7643213, 0.7021531,
0.7178306, 0.7330749, 0.6610618, 0.7961012, 0.7510821, 0.7799938,
0.6861423, 0.7155526, 0.739781, 0.725967, 0.6725775, 0.7637322,
0.7184616, 0.6760159
)), row.names = c(NA, -17L), class = "data.frame")
library(ggplot2)
# Make a new Date to get the correct order as with DAP.
# Set year for obs November and Decemeber to 2019,
# for other Obs to 2020,
df$Date1 <- gsub("20\\d{2}-(1\\d{1})", "2019-\\1", df$Date)
df$Date1 <- gsub("20\\d{2}-(0\\d{1})", "2020-\\1", df$Date1)
df$Date1 <- as.Date(df$Date1)
# use new date gives correcr order, spacing and labels
# Also adjusted limits
plot <- ggplot(data = df, aes(y = y, x = Date1, group = DAP)) +
geom_boxplot(fill = "grey85")
plot +
scale_x_date(date_breaks = "1 month", date_labels = "%B", limits = c(as.Date("2019-11-01"), as.Date("2020-03-31")))

Merging separate Month and Year columns to graph in ggplot2

I've been around the forums looking for a solution to my issue but can't seem to find anything. Derivatives of my question and their answer haven't really helped either. My data has four columns, one for Year and one for Month). I've been wanting to plot the data all in one graph without using any facets for years in ggplot. This is what I've been struggling with so far with:
df<-data.frame(Month = rep(c("January", "February", "March", "April", "May", "June",
"July", "August", "September", "October",
"November", "February", "March"),each = 20),
Year = rep(c("2018", "2019"), times = c(220, 40)),
Type = rep(c("C", "T"), 260),
Value = runif(260, min = 10, max = 55))
df$Month<-ordered(df$Month, month.name)
df$Year<-ordered(df$Year)
ggplot(df) +
geom_boxplot(aes(x = Month, y = Value, fill = Type)) +
facet_wrap(~Year)
I'd ideally like to manage this using dplyr and lubridate. Any help would be appreciated!
One option would be to make a true date value, then you can use the date axis formatter. Something like this is a rough start
ggplot(df) +
geom_boxplot(aes(x = lubridate::mdy(paste(Month, 1, Year)), y = Value, fill = Type, group=lubridate::mdy(paste(Month, 1, Year)))) +
scale_x_date(breaks="month", date_labels = "%m")
Do you mean this?
df<-data.frame(Month = rep(c("January", "February", "March", "April", "May", "June",
"July", "August", "September", "October",
"November", "February", "March"),each = 20),
Year = rep(c("2018", "2019"), times = c(220, 40)),
Type = rep(c("C", "T"), 260),
Value = runif(260, min = 10, max = 55))
df$Month <- factor(df$Month,levels=c("January", "February", "March", "April", "May", "June",
"July", "August", "September", "October",
"November", "Dicember"), ordered = T)
df$Month<-ordered(df$Month)
df$Year<-ordered(df$Year)
df$Year_Month <- paste0(df$Month, " ", df$Year)
df$Year_Month <- factor(df$Year_Month, levels = unique(df$Year_Month))
ggplot(df) +
geom_boxplot(aes(x = Year_Month, y = Value, fill = Type))

I would like to show the total of a variable across months, for different subgroups

I would like to use ggplot2 and dplyr to create a chart that can show how our halls perform across months. So From Aug-Dec, I would like to see three bars for each of the three halls, and their totals.
I've got the data prepped but I can't figure how to put this using the ggplot2 package.
#Events by Hall
fall2 <- fall %>%
group_by(Hall,Month) %>%
summarize(total = sum(Count))
#something like this?
ggplot(Fall2, aes(Hall, Month)) +
geom_col(aes(fill = total), position = "dodge") +
guides(fill=FALSE) +
ggtitle("Fall Events by Hall")
here's my data
fall2 <- structure(list(Hall = c("1959E", "1959E", "1959E", "1959E", "1959E",
"2109 F", "2109 F", "2109 F", "2109 F", "2109 F"), Month = c("August",
"December", "November", "October", "September", "August", "December",
"November", "October", "September"), total = c(2, 4, 5, 11, 8,
1, 3, 8, 7, 4)), row.names = c(NA, -10L), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"), vars = "Hall", drop = TRUE, indices = list(
0:4, 5:9), group_sizes = c(5L, 5L), biggest_group_size = 5L, labels = structure(list(
Hall = c("1959E", "2109 F")), row.names = c(NA, -2L), class = "data.frame", vars = "Hall", drop = TRUE))
In the end I would like x-axis to show various months, and within each month it's broken up by "Hall" Ideally if this were descending by Count that would be best.
Edit: modified to order in descending order of Count for each month, relying on the technique here: https://drsimonj.svbtle.com/ordering-categories-within-ggplot2-facets
You probably want your months in order. They're currently a character variable which will sort alphabetically. The fct_relevel line here makes them into an ordered factor, so that ggplot knows the order to use. (There's probably a less manual way to convert those, btw, but I don't know offhand...)
# library(tidyverse) # Loads all three and a few more
library(dplyr); library(forcats); library(ggplot2)
fall2$Month <- fall2$Month %>% fct_relevel("August", "September", "October", "November", "December")
fall2 <- fall2 %>%
ungroup() %>% # EDIT -- source data grouped
arrange(Month, -total) %>%
mutate(order = row_number())
#something like this?
ggplot(fall2, aes(order, total)) +
geom_col(aes(fill = total), position = "dodge") +
guides(fill=FALSE) +
ggtitle("Fall Events by Hall") +
facet_wrap(~Month, nrow = 1, scales = "free_x") +
scale_x_continuous(breaks = fall2$order, labels = fall2$Hall,expand = c(0,0))

change graph according to slider position

Here is my code. I am trying to make an rshiny page to show the mean symptoms in the past 30 days vesus the state based off of slider position (1 to 12 - for month). I know it is a little sloppy but I almost have it. I can get a graph that changes the title based off of the month on the slider but the graph just lists all of the data and not by month. Any help would be great.
`asthma = read.csv("AsthmaChild.Ozone.2006_2007.Sample.csv")
state.month = asthma[,-3:-10]
state.month = state.month[,-4]
state.month = aggregate(state.month$Symptoms.Past30D ~ state.month$STATE +
state.month$Month, state.month, mean)
colnames(state.month) = c("STATE", "Month", "Symptoms.Past30D")
sd = asthma[,-3:-10]
sd = sd[,-4]
sd = aggregate(sd$Symptoms.Past30D ~ sd$STATE + sd$Month, sd, function(x)
sd = sd(x))
colnames(sd) = c("STATE", "Month", "sd")
merged = merge(state.month,sd, by=c("STATE", "Month"))
df = count(asthma, "STATE", "Month")
colnames(df) = c("STATE","Freq")
data = merge(df, merged,by=c("STATE"))
data$sem = (data$sd)/(sqrt(data$Freq))
merged = data
merged$ConfUp = (merged$Symptoms.Past30D) + (merged$sem)
merged$ConfDown = (merged$Symptoms.Past30D) - (merged$sem)
merged$Month = as.character(merged$Month)
merged$Month = gsub("12", "December", merged$Month)
merged$Month = gsub("11", "November", merged$Month)
merged$Month = gsub("10", "October", merged$Month)
merged$Month = gsub("9", "September", merged$Month)
merged$Month = gsub("8", "August", merged$Month)
merged$Month = gsub("7", "July", merged$Month)
merged$Month = gsub("6", "June", merged$Month)
merged$Month = gsub("5", "May", merged$Month)
merged$Month = gsub("4", "April", merged$Month)
merged$Month = gsub("3", "March", merged$Month)
merged$Month = gsub("2", "February", merged$Month)
merged$Month = gsub("1", "January", merged$Month)
index = c(1:12)
values = c("January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December")
ui = fluidPage(
sidebarPanel(
sliderInput("Month", "Month: Jan=1, Dec=12",min = 1, max =
12,step=1,value=1)),
mainPanel(plotOutput("plot")))
server = function(input,output){
sliderInput(inputId="Month",
label="Month: Jan=1, Dec=12",
min = 1,
max = 12,
value=1,
step=1)
mainPanel(plotOutput("plot"))
dat = reactive({
test <- merged[merged$Month %in%
seq(from=min(input$Month),to=max(input$Month),by=1),]
})
output$plot = renderPlot({
ggplot(data=merged, aes(x=Symptoms.Past30D, y = STATE)) +
geom_errorbarh(aes(xmin=ConfUp,xmax=ConfDown), height=1, linetype = 1) +
xlab ("Mean Sympotms.Past30D (SEM)") + ylab ("STATE") +
labs(title=paste(values[match(input$Month, index)]))
})
}
shinyApp(ui, server)`

Resources