Home > Back-end >  How to convert time series dates into data frame dates
How to convert time series dates into data frame dates

Time:11-17

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).

CodePudding user response:

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.

CodePudding user response:

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)
}
  • Related