Converting weeks of year to dates - r

I have a data set with number of weeks from the beginning of the year (%W), which I would like to convert to dates in order to plot it using date on x-axis
dat <- structure(data.frame(week = c(22, 34, 15), year = c(2009, 2009, 2010), x = c(3.4, 5.2, 1.3)))
I try to convert the weeks based on earlier questions here, but end up getting "YYYY-10-01" for each date.
as.Date(paste("01", dat$week, dat$year, sep = "-"), format = "%d-%W-%Y")
Why is this and how can do it right?

Try this instead:
as.Date(paste("1", dat$week, dat$year, sep = "-"), format = "%w-%W-%Y")
A week and a year don't specify a date, so you do need a "day", but you need the "day of the week", or %w, rather than "day of the month", or %d. In this case, I used Monday (i.e. 1). Also, apparently %w doesn't like leading zeros.

Related

A calendar issues in wavelet analyze

I want to apply a simple wavelet analyze using "waveletcomp" package. I want to use the year shown in x-axis. But it always report error in "lease check your calendar dates, format and time zone: dates may not be in an unambiguous format or chronological. The default numerical axis was used instead." I tried to fix the date, but it seems fine. I really don't know where is the wrong part. Thank you in advance.
Here is the code.
library('WaveletComp')
firecount <- data.frame( YEAR = c("1986-01-01","1987-01-01","1988-01-01","1989-01-01","1990-01-01"
,"1991-01-01","1992-01-01","1993-01-01","1994-01-01","1995-01-01"
,"1996-01-01","1997-01-01","1998-01-01","1999-01-01","2000-01-01"
,"2001-01-01","2002-01-01","2003-01-01","2004-01-01","2005-01-01"
,"2006-01-01","2007-01-01","2008-01-01","2009-01-01","2010-01-01"
,"2011-01-01","2012-01-01","2013-01-01","2014-01-01","2015-01-01"
,"2016-01-01","2017-01-01","2018-01-01","2019-01-01","2020-01-01"
),
COUNT = c(3,5,4,0,0,0,13,0,2,3,0,1,0,3,15,13,
59,18,42,16,20,46,44,8,68,18,7,3,9
,48,7,48,23,84,54)
)
flycount$YEAR <- as.Date(as.character(firecount$YEAR),"%Y")
my.w <- analyze.wavelet(flycount, my.series = "COUNT",
loess.span = 0.5,
dt = 1, dj = 1/35,
lowerPeriod = 2, upperPeriod = 12,
make.pval = TRUE, n.sim = 10,
)
wt.image(my.w, color.key = "interval", n.levels = 15,
legend.params = list(lab = "fire occurrence wavelet", label.digits = 2),
periodlab = "periods (years)",
# Concerning item 1 above --- plot the square root of power:
exponent = 0.5,
# Concerning item 2 above --- time axis:
show.date = TRUE,
date.format = "%F",
timelab = "",
spec.time.axis = list(at = c(paste(1986:2020, "-01-01", sep = "")),
labels = c(1986:2020)),
timetcl = -0.5)
The function analyze.wavelet automatically takes the date from a dataframe column called date. So just rename your column from YEAR to date and you're good to go.

R Shiny DateRangeInput Select Only Specific Days

I'm working on creating a shiny dashboard using R Shiny. I'm using selectInput to choose a view(Daily, Weekly, Monthly, Yearly) and a dateRangeInput which will allow the user to choose the dates the plots should display. The plots are made using Plotly.
Custom date range input to allow min/max views for dates(credit here):
CustomDateRangeInput <- function(inputId, label, minview = "days", maxview = "decades", ...) {
d <- shiny::dateRangeInput(inputId, label, ...)
d$children[[2L]]$children[[1]]$attribs[["data-date-min-view-mode"]] <- minview
d$children[[2L]]$children[[3]]$attribs[["data-date-min-view-mode"]] <- minview
d$children[[2L]]$children[[1]]$attribs[["data-date-max-view-mode"]] <- maxview
d$children[[2L]]$children[[3]]$attribs[["data-date-max-view-mode"]] <- maxview
d
}
Code for creating the dateRangeInput based on the selected view:
output$asymp_dates <- renderUI({
switch (
input$id_view,
"Daily" = {
data <- GetDateRangeData(asymp, "day")
dateRangeInput("id_asymp_dates", "Date Range", min(data$Date), max(data$Date), min(data$Date), max(data$Date), "mm/dd/yyyy", "month")
},
"Weekly" = {
data <- GetDateRangeData(asymp, "week")
dateRangeInput("id_asymp_dates", "Date Range", min(data$Date), max(data$Date), min(data$Date), max(data$Date), "mm/dd/yyyy", "month")
},
"Monthly" = {
data <- GetDateRangeData(asymp, "month")
min_date <- min(floor_date(data$Date, "month"))
max_date <- max(ceiling_date(data$Date, "month")) - 1
CustomDateRangeInput("id_asymp_dates", "Date Range", "year", "decades", min_date, max_date, min_date, max_date, "MM, yyyy", "year")
},
"Yearly" = {
data <- GetDateRangeData(asymp, "year")
min_date <- min(floor_date(data$Date, "year"))
max_date <- max(ceiling_date(data$Date, "year")) - 1
CustomDateRangeInput("id_asymp_dates", "Date Range", "decades", "decades", min_date, max_date, min_date, max_date, "yyyy", "decades")
# The calculation is needed in order to reset the date range,
# but we don't want the date range editable.
shinyjs::disable("id_asymp_dates")
}
)
})
Everything works fine, but I would like for the weekly view to only be able to select the first/last day of each week so that my date ranges go from the start date being a beginning of a week and the end date being the end of a week.
ie:
dateRangeInput Calendar
March 8 - March 14, March 15 - March 21, and March 22 - March 28 are weeks. I want to be able to only select March 8, March 15, or March 22 as the first date and then March 14, March 21, or March 28 as my end date.

Dynamic Time Series Function R

I currently have a time series of football data for weekly stats for variables such as shots and goals. I want to create a "form" function with input for number of games (specify date) and the variable of choice (shots, goals, etc) so that I can check the form of players for certain stats over the last 4 games, 6 games or whatever period I specify. The data frame is of the form:
week = as.vector(c(rep(25, 5), rep(26, 5), rep(27, 5)))
date = as.vector(c(rep("2019-08-09 15:00:00", 5), rep("2019-08-16 15:00:00", 5), rep("2019-08-23 15:00:00", 5)))
players = c("Player 1", "Player 2", "Player 3", "Player 4", "Player 5")
name = as.vector(c(rep(players, 3)))
goals = as.vector(sample(c(0:2), 15, replace = T))
shots = as.vector(sample(c(0:8), 15, replace = T))
data = data.frame(week, date, name, goals, shots)
Would it make sense to create a function using dplyr and input variables for time period and variable type? Or is there some package that will do this for me?
This answer could give you some idea how to filter the data frame for date or games played as specified in the comments:
library(tidyverse)
library(lubridate)
data = tibble(
week = rep(31:40, each = 2),
date = seq.Date(ymd("2019-01-01"), length.out = 20, by = "months"),
name = paste0("player", rep(1:4, each = 5)),
goals = sample(c(0:2), 20, replace = T),
shots = sample(c(0:8), 20, replace = T)
)
# last 3 months or after
data %>%
filter(date > (today() %m-% months(3) ))
# last 5 games
data %>%
filter(week > (max(week) - 4) )

Creating a Gantt chart/timeline in R using only yyyy, not dd-mm-yyy

I am summarising the evidence cited by different trials in their reference sections. I want to display the earliest and most recent cited papers on a chart along with the year of publication of the actual trial. I have tried solutions using ggplot, base plot function, and googleVis, but with no luck.
What I want is sort of like a Gantt chart, with the name of the trials on y-axis and the years (yyyy) on the x-axis. I've run into trouble because most Gantt chart code out there works on Dates, and also can't handle the three elements I need on the chart -
Earliest reference
Latest reference
Date of publication
poorly drawn postit of what I'm trying to achieve
Update:
This is close to what I want, and this code works very well, thank you. I'm glad you did it in ggplot too, i'm used to that package.
I also need to add a third class (pubdate) onto the chart, so the df is
df <- structure(list(task = structure(1:3, .Label = c("Trial1", "Trial2", "Trial3"),
class = "factor"), start_year = c(1980, 2003, 2000),
end_year = c(2006, 2013, 2010), pub_date = c(2011, 2015, 2013)),
class = "data.frame",
row.names = c(NA, 3L))
I would like pub_date to be separated from the start_year<->end_year line on the graph.
This is a reproducible example of what you want. First you should have the start and end date of each task in your agenda, and the diferent tasks store as a factor in your data frame as follow.
df <- structure(list(task = structure(1:3, .Label = c("Trial1", "Trial2",
"Trial3"), class = "factor"), start_year = c(1980, 2003, 2000
), end_year = c(2006, 2013, 2010), pub_date = c(2011, 2015, 2013
)), class = "data.frame", row.names = c(NA, 3L))
Something inportant is to tidy your dates, using gather function from the tidyr package, for example. This way i put start and end years in the same column so it could be easier to plot by task.
library(tidyverse)
df %>%
gather(key = "start_end_date)", value = "year", -task, -pub_date) %>%
ggplot(aes(x = year, y = task, color = task)) +
geom_line(size = 2) +
geom_point(size = 3) +
geom_point(aes( x = pub_date), shape = 3, size = 3) +
scale_x_continuous(breaks = seq(1980, 2016, 6))

Weekly data plot in R

I have a big data frame (from 2007 to 2015), with data points at about every 2 minutes. I want to plot the graph of every week (from 2007 to 2015), with each week being automatically exported as a PNG file to my computer's folder. Previously, I was able to successfully produce working codes for annually, monthly, and daily plot. E.g.for yearly data:
for(j in 2007:2015){
mypath <- file.path("~", "Documents","Yearly", paste("WAO_AIR_Data_", j, ".png", sep = "" ))
png(filename = mypath, width = 963, height = 690)
timePlot(selectByDate(new_subdata, year = j),
pollutant = c("CO2", "O2", "APO"),
date.pad = TRUE,
pch = c(19,19,19),
cex = 0.2,
xlab = paste("Month of year in", j),
ylab = "CO2, O2, and APO concentrations",
name.pol = c("CO2 (ppm)", "O2 (per meg)", "APO (per meg)"),
)
dev.off()
}
The data frame looks like this
tail(new_subdata)
date CO2 O2 APO
1052042 2015-12-31 23:48:45 409.636 -666.39 -353.27
1052043 2015-12-31 23:50:46 409.652 -669.62 -356.41
1052044 2015-12-31 23:52:44 409.679 -669.44 -356.09
1052045 2015-12-31 23:54:46 409.703 -667.07 -353.59
1052046 2015-12-31 23:56:44 409.719 -671.02 -357.46
1052047 2015-12-31 23:58:46 409.734 NA NA
But I dont know how to produce the code for weekly plotting. Can anyone help me please? Thank you so much!
Via ?strptime, you can get the week out of a Date or POSIXct with %U
%U
Week of the year as decimal number (00–53) using Sunday as the first day 1 of the week (and typically with the first Sunday of the year as day 1 of week 1). The US convention.
x <- Sys.time()
class(x); format(x, '%U')
# [1] "POSIXct" "POSIXt"
# [1] "26"
x <- Sys.Date()
class(x); format(x, '%U')
# [1] "Date"
# [1] "26"
Using your example data with minor changes:
new_subdata <- read.table(header = TRUE, text = "date CO2 O2 APO
1052042 '2015-10-31 23:48:45' 409.636 -666.39 -353.27
1052043 '2015-10-31 23:50:46' 409.652 -669.62 -356.41
1052044 '2015-11-30 23:52:44' 409.679 -669.44 -356.09
1052045 '2015-11-30 23:54:46' 409.703 -667.07 -353.59
1052046 '2015-12-31 23:56:44' 409.719 -671.02 -357.46
1052047 '2015-12-31 23:58:46' 409.734 NA NA")
## create a new grouping variable with year/week
new_subdata <- within(new_subdata, {
yr_wk <- format(as.Date(date), '%Y %U')
})
## iterate over the unique values
jj <- unique(new_subdata$yr_wk)
# [1] "2015 43" "2015 48" "2015 52"
## do some plotting
par(mfrow = n2mfrow(length(jj)), las = 1, mar = c(5,6,2,2),
tcl = .2, mgp = c(3,.25,0))
xr <- range(new_subdata$O2, na.rm = TRUE)
yr <- range(new_subdata$CO2, na.rm = TRUE)
for (j in jj) {
mypath <- file.path("~", "Documents","Yearly", sprintf("WAO_AIR_Data_%s.png", j))
# png(filename = mypath, width = 963, height = 690)
plot(CO2 ~ O2, data = subset(new_subdata, yr_wk == j), xlim = xr, ylim = yr)
# dev.off()
}

Resources