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>
Related
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.
I have a data frame in R. It has a column containing dates in this format Dec-06, Jan-90, Feb-76 etc. They are strings. How can I extract year section of it in this format: 2006, 1990, 1976 etc? I want to discard month segment and treat it as distance on year portion of it and treat this column as continuous variable for my logistic regression.
I tried several Date format package provided in R like POSIX, lubridate etc but was not able to extract.
Any idea?
format(as.Date(gsub(".*-","","Dec-06"), format = "%y"), "%Y")
#[1] "2006"
OR
library(lubridate)
format(myd(paste("Dec-06","-01",sep="")), "%Y")
#[1] "2006"
We convert the string into a Date class and then extract only the year from it.
format(as.Date(paste0("01-", x), "%d-%b-%y"), "%Y")
#[1] "2006" "1990" "1976"
data
x <- c("Dec-06", "Jan-90", "Feb-76 ")
Using lubridate , it is easy, year function is a part of lubridate:
library(lubridate)
dat <- data.frame(x=c("Mar-06","Jan-90","May-76"))
dat$date <- as.POSIXlt(paste0("01-",tolower(dat$x)),format="%d-%b-%y",origin="1970-01-01")
dat$year <- year(dat$date)
Answer:
> dat
x date year
1 Mar-06 2006-03-01 2006
2 Jan-90 1990-01-01 1990
3 May-76 1976-05-01 1976
Here is another option with zoo
library(zoo)
data.table::year(as.yearmon("Dec-06", "%b-%y"))
#[1] 2006
Or as #G.Grothendieck mentioned, as.integer returns the year
as.integer(as.yearmon("Dec-06", "%b-%y"))
#[1] 2006
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")
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
I was wondering if there is a way to get the begin of the week date based on a week number in R? For example, if I enter week number = 10, it should give me 9th March, 2014.
I know how to get the reverse (aka..given a date, get the week number by using as.POSIX functions).
Thanks!
Prakhar
You can try this:
first.day <- as.numeric(format(as.Date("2014-01-01"), "%w"))
week <- 10
as.Date("2014-01-01") + week * 7 - first.day
# [1] "2014-03-09"
This assumes weeks start on Sundays. First, find what day of the week Jan 1 is, then, just add 7 * number of weeks to Jan 1, - the day of week Jan 1 is.
Note this is slightly different to what you get if you use %W when doing the reverse, as from that perspective the first day of the week seems to be Monday:
format(seq(as.Date("2014-03-08"), by="1 day", len=5), "%W %A %m-%d")
# [1] "09 Saturday 03-08" "09 Sunday 03-09" "10 Monday 03-10" "10 Tuesday 03-11"
# [5] "10 Wednesday 03-12"
but you can adjust the above code easily if you prefer the Monday centric view.
You may try the ISOweek2date function in package ISOweek.
Create a function which takes year, week, weekday as arguments and returns date(s):
date_in_week <- function(year, week, weekday){
w <- paste0(year, "-W", sprintf("%02d", week), "-", weekday)
ISOweek2date(w)
}
date_in_week(year = 2014, week = 10, weekday = 1)
# [1] "2014-03-03"
This date is corresponds to an ISO8601 calendar (see %V in ?strptime). I assume you are using the US convention (see %U in ?strptime). Then some tweeking is needed to convert between ISO8601 and US standard:
date_in_week(year = 2014, week = 10 + 1, weekday = 1) - 1
# [1] "2014-03-09"
You can enter several weekdays, e.g.
date_in_week(year = 2014, week = 10 + 1, weekday = 1:3) - 1
# [1] "2014-03-09" "2014-03-10" "2014-03-11"
You can also use strptime to easily get dates from weeks starting on Mondays:
first_date_of_week <- function(year, week){
strptime(paste(year, week, 1), format = "%Y %W %u")
}
You can accomplish this using the package lubridate
library(lubridate)
start = ymd("2014-01-01")
#[1] "2014-01-01 UTC"
end = start+10*weeks()
end = end-(wday(end)-1)*days()
#[1] "2014-03-09 UTC"