Convert date to day-of-week in R - r

I have a date in this format in my data frame:
"02-July-2015"
And I need to convert it to the day of the week (i.e. 183). Something like:
df$day_of_week <- weekdays(as.Date(df$date_column))
But this doesn't understand the format of the dates.

You could use lubridate to convert to day of week or day of year.
library(lubridate)
# "02-July-2015" is Thursday
date_string <- "02-July-2015"
dt <- dmy(date_string)
dt
## [1] "2015-07-02 UTC"
### Day of week : (1-7, Sunday is 1)
wday(dt)
## [1] 5
### Day of year (1-366; for 2015, only 365)
yday(dt)
## [1] 183
### Or a little shorter to do the same thing for Day of year
yday(dmy("02-July-2015"))
## [1] 183

day = as.POSIXct("02-July-2015",format="%d-%b-%Y")
# see ?strptime for more information on date-time conversions
# Day of year as decimal number (001–366).
format(day,format="%j")
[1] "183"
#Weekday as a decimal number (1–7, Monday is 1).
format(day,format="%u")
[1] "4"

This is what anotherFishGuy supposed, plus converting the values to as.numeric so they fit through classifier.
# day <- Sys.time()
as.num.format <- function(day, ...){
as.numeric(format(day, ...))
}
doy <- as.num.format(day,format="%j")
doy <- as.num.format(day,format="%u")
hour <- as.num.format(day, "%H")

Related

How to convert time series dates into data frame dates

I have a time series of weekly data, beginning at Jan. 1, 2016. I've tried using the method in this question, but getting dates from 1970.
This is what I'm doing below:
# Creating this df of dates used later on
index.date <- data.frame(start.date=seq(from=as.Date("01/01/2016",format="%m/%d/%Y"),
to=as.Date("10/30/2021",format="%m/%d/%Y"),
by='week'))
# Create a ts, specifying start date and frequency=52 for weekly
weekly.ts <- ts(rnorm(305,0,1),start=min(index.date$start.date), frequency = 52)
# Look at the min and max dates in the ts
as.Date(as.numeric(time(min(weekly.ts))))
[1] "1970-01-02"
as.Date(as.numeric(time(max(weekly.ts))))
[1] "1970-01-02"
I plan to place the ts into a df with dates shown in a date format with the following:
# Place ts dates and values into a df
output.df <-data.frame(date=as.Date(as.numeric(time(weekly.ts))),
y=as.matrix(weekly.ts))
Is this a matter of me specifying the dates incorrectly in the ts, or am I converting them incorrectly with as.Date(as.numeric(timeweekly.ts))))? I would expect the min date to be Jam. 1, 2016, and the maximum Oct. 29, 2021 (as it is for index.date).
ts series do not understand Date class but you can encode the dates into numbers and then decode them back. Assuming that you want a series with frequency 52 the first week in 2016 will be represented by 2016, the second by 2016+1/52, ..., the last by 2016+51/52.
For example,
tt <- ts(rnorm(305), start = 2016, freq = 52)
Now decode the dates.
toDate <- function(tt) {
yr <- as.integer(time(tt))
week <- as.integer(cycle(tt)) # first week of year is 1, etc.
as.Date(ISOdate(yr, 1, 1)) + 7 * (week - 1)
}
data.frame(dates = toDate(tt), series = c(tt))
We can also convert from Date class to year/week number
# input is a Date class object
to_yw <- function(date) {
yr <- as.numeric(format(date, "%Y"))
yday <- as.POSIXlt(date)$yday # jan 1st is 0
week <- pmin(floor(yday / 7), 51) + 1 # 1st week of yr is 1
yw <- yr + (week - 1) / 52
list(yw = yw, year = yr, yday = yday, week = week)
}
Try this
weekly.ts <- ts(rnorm(305,0,1),
start=min(index.date$start.date),
end=max(index.date$start.date), frequency=2)
# look at plot to see if it works
plot(stl(weekly.ts, s.window=2))
# get time
head(as.POSIXlt.Date(time(weekly.ts)))
[1] "2016-01-01 UTC" "2016-01-01 UTC" "2016-01-02 UTC" "2016-01-02 UTC"
[5] "2016-01-03 UTC" "2016-01-03 UTC"
tail(as.POSIXlt.Date(time(weekly.ts)))
[1] "2021-10-26 UTC" "2021-10-27 UTC" "2021-10-27 UTC" "2021-10-28 UTC"
[5] "2021-10-28 UTC" "2021-10-29 UTC"
You get 2 dates because of freqency=2, which is required by decompose or stl for meaningful data.

extract month from a character year and doy in R

Given a year and a day (in Julian day), how can I extract the month? For e.g.
Year <- '2000'
Doy <- '159'
I want to extract the month for the above Year and Doy. I thought first I will convert this into date and then extract the month out of it using format(mydate,"%m")
# first convert into date and then extract the month
as.Date(paste0(Year'-',Doy), format = '%Y-%d')
NA
This gives me NA.
%d is for day of month. %j is for day of year where Jan 1 is day of year 1, Jan 2 is day of year 2, ..., Dec 31 is day of year 365 (or 366 on leap years). See ?strptime for the percent codes.
Year <- '2000'
Doy <- '159'
date <- as.Date(paste(Year, Doy), format = "%Y %j"); date
## [1] "2000-06-07"
as.numeric(format(date, "%m")) # month number
## [1] 6

How do I find the first and last day of next month?

If I have a given date, how do I find the first and last days of the next month?
For example,
today <- as.Date("2009-04-04")
I want to find
# first date in next month
"2009-05-01"
# last date in next month
"2009-05-31"
You can do this with base R:
today <- as.Date("2009-04-04")
first <- function(x) {
x <- as.POSIXlt(x)
x$mon[] <- x$mon + 1
x$mday[] <- 1
x$isdst[] <- -1L
as.Date(x)
}
first(today)
#[1] "2009-05-01"
first(first(today)) - 1
#[1] "2009-05-31"
lubridate has some useful tools for this purpose.
library(lubridate)
today <- ymd("2009-04-12")
# First day of next month
first <- ceiling_date(today, unit = "month")
# Last day of next month
last <- ceiling_date(first, unit= "month") -1
first
#"2009-05-01"
last
#"2009-05-31"
Here are some solutions. We use today from the question to test. In both cases the input may be a Date class vector.
1) Base R Define function fom to give the first of the month of its Date
argument. Using that we can get the date of the first and last of the next month as follows. We use the facts that 31 and 62 days after the first of the month is necessarily a date in the next month and month after the next month.
fom <- function(x) as.Date(cut(x, "month"))
fom(fom(today) + 31)
## [1] "2009-05-01"
fom(fom(today) + 62) - 1
## [1] "2009-05-31"
2) yearmon yearmon class objects internally represent a year and month as the year plus 0 for January, 1/12 for Febrary, 2/12 for March and so on. Using as.Date.yearmon the frac argument specifies the fraction of the way through the month to output. The default is frac = 0 and results in the first of the month being output and frac = 1 means the end of the month.
library(zoo)
as.Date(as.yearmon(today) + 1/12)
## [1] "2009-05-01"
as.Date(as.yearmon(today) + 1/12, frac = 1)
## [1] "2009-05-31"

R - convert POSIXct to fraction of julian day

How can a date/time object in R be transformed on the fraction of a julian day?
For example, how can I turn this date:
date <- as.POSIXct('2006-12-12 12:00:00',tz='GMT')
into a number like this
> fjday
[1] 365.5
where julian day is elapsed day counted from the january 1st. The fraction 0.5 means that it's 12pm, and therefore half of the day.
This is just an example, but my real data covers all the 365 days of year 2006.
Since all your dates are from the same year (2006) this should be pretty easy:
julian(date, origin = as.POSIXct('2006-01-01', tz = 'GMT'))
If you or another reader happen to expand your dataset to other years, then you can set the origin for the beginning of each year as follows:
sapply(date, function(x) julian(x, origin = as.POSIXct(paste0(format(x, "%Y"),'-01-01'), tz = 'GMT')))
Have a look at the difftime function:
> unclass(difftime('2006-12-12 12:00:00', '2006-01-01 00:00:00', tz="GMT", units = "days"))
[1] 345.5
attr(,"units")
[1] "days"
A function to convert POSIX to julian day, an extension of the answer above, source it before using.
julian_conv <- function(x) {
if (is.na(x)) { # Because julian() cannot accept NA values
return(NA)
}
else {
j <-julian(x, origin = as.POSIXlt(paste0(format(x, "%Y"),'-01-01')))
temp <- unclass(j) # To unclass the object julian day to extract julian day
return(temp[1] + 1) # Because Julian day 1 is 1 e.g., 2016-01-01
}
}
Example:
date <- as.POSIXct('2006-12-12 12:00:00')
julian_conv(date)
#[1] 345.5

How to convert number to Julian date in r?

day <- c(seq(1, 10592, by = 1))
How to change 'day' into Julian date format from 1st January 1982 to 31st December 2010).
Thanks in advance.
Try help.search("Julian") -- there is a function julian.
So given your date sequence (and replace the length=... with by="1 day" for all dates)
R> seq(as.Date("1982-01-01"), as.Date("2010-12-31"), length=5)
[1] "1982-01-01" "1989-04-01" "1996-07-01" "2003-10-01" "2010-12-31"
R>
you compute Julian dates just by calling the function:
R> julian(seq(as.Date("1982-01-01"), as.Date("2010-12-31"), length=5))
[1] 4383.00 7030.75 9678.50 12326.25 14974.00
attr(,"origin")
[1] "1970-01-01"
R>

Resources