Skip to content
Prev 15134 / 15274 Next

xts: Transfer/expand values to higher periodicity

On Sun, Aug 13, 2023 at 6:45?PM Mike <mike9 at posteo.nl> wrote:
The issue was with your initial example because
    x.daily <- as.xts(sample_matrix)
creates an xts object with a POSIXct index with TZ=""

to.weekly() creates an xts object with a Date index, and TZ="UTC" for
all xts objects that have an index without a time component. So you
get this result when you merge the two:

    head(x.daily.new <- merge(x.daily, x.weekly$M))
    ##                         Open     High      Low    Close        M
    ## 2007-01-02 00:00:00 50.03978 50.11778 49.95041 50.11778       NA
    ## 2007-01-03 00:00:00 50.23050 50.42188 50.23050 50.39767       NA
    ## 2007-01-04 00:00:00 50.42096 50.42096 50.26414 50.33236       NA
    ## 2007-01-04 18:00:00       NA       NA       NA       NA 50.18615
    ## 2007-01-05 00:00:00 50.37347 50.37347 50.22103 50.33459       NA
    ## 2007-01-08 00:00:00 50.03555 50.10363 49.96971 49.98806       NA

This happens any time you merge xts objects with a timezone with xts
objects that don't have a timezone (i.e. Date, yearmon, yearqtr, etc.
because they have TZ="UTC").

In the case where you want to align >= daily data with intraday data,
you need to make sure your >= daily data index is POSIXct in the same
timezone. You can keep the timezone with to.weekly() and friends by
setting drop.time = FALSE. For example

    dttm.hourly <- seq(as.POSIXct(start(x.daily)), by="hour", length.out=24*30)
    y.hourly <- xts(seq_along(dttm.hourly), dttm.hourly)
    y.daily <- to.daily(y.hourly, name = NULL, drop.time = FALSE)
    tail(y.hourly.new <- merge(y.hourly, y.daily[, "Close"], fill =
na.locf), 30)
    ##                     y.hourly Close
    ## 2007-01-30 18:00:00      691   672
    ## 2007-01-30 19:00:00      692   672
    ## 2007-01-30 20:00:00      693   672
    ## 2007-01-30 21:00:00      694   672
    ## 2007-01-30 22:00:00      695   672
    ## 2007-01-30 23:00:00      696   696
    ## 2007-01-31 00:00:00      697   696
    ## 2007-01-31 01:00:00      698   696
    ## 2007-01-31 02:00:00      699   696
    ## 2007-01-31 03:00:00      700   696
    ## 2007-01-31 04:00:00      701   696
    ## 2007-01-31 05:00:00      702   696
    ## 2007-01-31 06:00:00      703   696
    ## 2007-01-31 07:00:00      704   696
    ## 2007-01-31 08:00:00      705   696
    ## 2007-01-31 09:00:00      706   696
    ## 2007-01-31 10:00:00      707   696
    ## 2007-01-31 11:00:00      708   696
    ## 2007-01-31 12:00:00      709   696
    ## 2007-01-31 13:00:00      710   696
    ## 2007-01-31 14:00:00      711   696
    ## 2007-01-31 15:00:00      712   696
    ## 2007-01-31 16:00:00      713   696
    ## 2007-01-31 17:00:00      714   696
    ## 2007-01-31 18:00:00      715   696
    ## 2007-01-31 19:00:00      716   696
    ## 2007-01-31 20:00:00      717   696
    ## 2007-01-31 21:00:00      718   696
    ## 2007-01-31 22:00:00      719   696
    ## 2007-01-31 23:00:00      720   720
Yes, as I showed above.
It could be a problem if x.weekly was created with to.weekly(...,
drop.time = TRUE) because that would remove the timezone from the
result. So make sure to use drop.time = FALSE as I did in my example
above. Or it might work if you provide the appropriate value for the
'tz' argument to as.POSIXct().