Subsetting in Xts Using a Parameter Holding Dates

subsetting in xts using a parameter holding dates

You could paste the start.date and end.date objects together, separating by "::" or "/", and then use that to subset.

R> xts.obj[paste(start.date,end.date,sep="::")]
[,1]
2012-11-03 09:45:00 1

Improving performance in multiple Time-Range subsetting from xts?

This solution will be faster if the bottleneck was rbind.xts, but the bottleneck is the time-of-day subsetting.

jv <- j[unlist(lapply(v, function(i) j[i, which.i=TRUE])),]

Time-of-day subsetting in a non-UTC timezone is slow because xts currently converts the POSIXct index into POSIXlt to get the day of the year.

How can I query an xts time range using indexes rather than string

ISO-style character subsetting by range (i.e. a length 1 vector containing : or /) is very fast. So you should use something like this :

a[paste(index(a)[4],index(a)[7],sep='::')]
[,1]
2013-04-15 17:26:57 7
2013-04-15 17:26:57 9
2013-04-15 17:26:57 8
2013-04-15 17:26:59 2

xts subclass subsetting approach

You need to create a subsetting function for your subclass that handles the columnar metadata attributes:

`[.dm` <- function(x, i, j, drop=FALSE, which.i=FALSE, ...) {
# Include all args from [.xts (check by running args(xts:::`[.xts`))
# Call the regular xts subsetting function
res <- xts:::`[.xts`(x, i, j, drop, which.i, ...)
cnx <- colnames(x) # Get colnames from x
ncn <- is.null(cnx) # Check if there are no colnames
if(ncn) # If there are no colnames, add them
colnames(x) <- sprintf("X%d",1:ncol(x))
# Determine which columns are in the resulting object
cols <- which(cnx %in% colnames(res))
# Get the 'KEY' attributes from x
xa <- xtsAttributes(x)
# Replace the 'KEY' attributes with values from columns we keep
xtsAttributes(res) <- list(KEY1=xa$KEY1[cols], KEY2=xa$KEY2[cols])
if(ncn) # Remove our colnames from res
colnames(res) <- NULL
res # return result
}

Now that we've defined the subclass subsetting function, let's test it:

> str(d[,1])
An ‘xts’ object from 2012-08-07 16:08:47 to 2012-08-07 16:08:56 containing:
Data: num [1:10, 1] 0 0.643 0.985 0.866 0.342 ...
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr "col"
Indexed by objects of class: [POSIXct,POSIXt] TZ:
xts Attributes:
List of 4
$ tclass: chr [1:2] "POSIXct" "POSIXt"
$ tzone : chr ""
$ KEY1 : chr "desc k1 - 1"
$ KEY2 : chr "desc k2 - 1"
> str(d[,2])
An ‘xts’ object from 2012-08-07 16:08:47 to 2012-08-07 16:08:56 containing:
Data: num [1:10, 1] 1 0.766 0.174 -0.5 -0.94 ...
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr "col2"
Indexed by objects of class: [POSIXct,POSIXt] TZ:
xts Attributes:
List of 4
$ tclass: chr [1:2] "POSIXct" "POSIXt"
$ tzone : chr ""
$ KEY1 : chr "desc k1 - 2"
$ KEY2 : chr "desc k2 - 2"

Looks good. Note that you can continue to use the xts-style subsetting functionality:

> str(d["2012-08-07 16:08:50",1])
An ‘xts’ object from 2012-08-07 16:08:50 to 2012-08-07 16:08:50 containing:
Data: num [1, 1] 0.866
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr "col"
Indexed by objects of class: [POSIXct,POSIXt] TZ:
xts Attributes:
List of 4
$ tclass: chr [1:2] "POSIXct" "POSIXt"
$ tzone : chr ""
$ KEY1 : chr "desc k1 - 1"
$ KEY2 : chr "desc k2 - 1"
> str(d["2012-08-07 16:08:50",2])
An ‘xts’ object from 2012-08-07 16:08:50 to 2012-08-07 16:08:50 containing:
Data: num [1, 1] -0.5
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr "col2"
Indexed by objects of class: [POSIXct,POSIXt] TZ:
xts Attributes:
List of 4
$ tclass: chr [1:2] "POSIXct" "POSIXt"
$ tzone : chr ""
$ KEY1 : chr "desc k1 - 2"
$ KEY2 : chr "desc k2 - 2"

Finding the maximum in an xts column within the last X hrs

As far as I'm familiar with xts, your startdate/enddate part has simply to be a string, c.f. Joshua's response here. That's it.

# allow me to create an xts object beforehand
datetimes <- c("2022-07-21 12:10 AM",
"2022-07-21 12:11 AM",
"2022-07-21 12:12 AM",
"2022-07-21 12:13 AM",
"2022-07-21 12:14 AM",
"2022-07-21 12:15 AM") |>
strptime(format = "%Y-%m-%d %I:%M %p") |>
as.POSIXct()

data <- c(400.1, 33.9, 32.5, 35.1, 31.5, 39.5)

xts <- xts::xts(data, order.by = datetimes)

# minor adjustments to your approach
enddate <- end(xts)
startdate <- enddate - (5-1) * 60

xts[paste0(startdate, enddate, sep = "/")] |> max()
#> [1] 39.5

# assuming you are interested in the last five observations
xts |> utils::tail(5) |> max()
#> [1] 39.5


Related Topics



Leave a reply



Submit