1) R version 3.4.4 (2018-03-15)
my.timedate <- as.POSIXlt('2016-01-01 16:00:00')
# print(attributes(my.timedate))
print(my.timedate[['hour']])
[1] 16
2) R version 3.5.0 (2018-04-23)
my.timedate <- as.POSIXlt('2016-01-01 16:00:00')
# print(attributes(my.timedate))
print(my.timedate[['hour']])
Error in FUN(X[[i]], ...) : subscript out of bounds
I think that is a known change in R 3.5.0 where the list elements of a POSIXlt
need to be unpackaged explicitly. Using R 3.5.0:
edd@rob:~$ docker run --rm -ti r-base:3.5.0 \
R -q -e 'print(unclass(as.POSIXlt("2016-01-01 16:00:00")[["hour"]])'
> print(unclass(as.POSIXlt("2016-01-01 16:00:00"))[["hour"]])
[1] 16
>
>
edd@rob:~$
whereas with R 3.4.* one does not need the unclass()
as you showed:
edd@rob:~$ docker run --rm -ti r-base:3.4.3 \
R -q -e 'print(as.POSIXlt("2016-01-01 16:00:00")[["hour"]])'
> print(as.POSIXlt("2016-01-01 16:00:00")[["hour"]])
[1] 16
>
>
edd@rob:~$
I don't find a corresponding NEWS file entry though so not entirely sure if it is on purpose...
Edit: As others have noted, the corresponding NEWS entry is the somewhat opaque
* Single components of "POSIXlt" objects can now be extracted and replaced via [ indexing with 2 indices.
From ?POSIXlt
:
As from R 3.5.0, one can extract and replace single components via
[
indexing with two indices (see the examples).
The example is a little opaque, but shows the idea:
leapS[1 : 5, "year"]
If you look at the source, though, you can see what's happening:
`[.POSIXlt`
#> function (x, i, j, drop = TRUE)
#> {
#> if (missing(j)) {
#> .POSIXlt(lapply(X = unclass(x), FUN = "[", i, drop = drop),
#> attr(x, "tzone"), oldClass(x))
#> }
#> else {
#> unclass(x)[[j]][i]
#> }
#> }
#> <bytecode: 0x7fbdb4d24f60>
#> <environment: namespace:base>
It is using i
to subset unclass(x)
, where x
is the POSIXlt object. So with R 3.5.0, you use [
and preface the part of the datetime you want with the index of the datetime in the vector:
my.timedate <- as.POSIXlt('2016-01-01 16:00:00')
my.timedate[1, 'hour']
#> [1] 16
as.POSIXlt(seq(my.timedate, by = 'hour', length.out = 10))[2:5, 'hour']
#> [1] 17 18 19 20
Note that $
subsetting still works as usual:
my.timedate$hour
#> [1] 16
See ?DateTimeClasses
(same as ?as.POSIXlt
):
As from R 3.5.0, one can extract and replace single components via
[
indexing with two indices
See also similar description in R NEWS CHANGES IN R 3.5.0.
Thus:
my.timedate[1, "hour"]
# [1] 16
# or leave the i index empty to select a component
# from all date-times in a vector
as.POSIXlt(c('2016-01-01 16:00:00', '2016-01-01 17:00:00'))[ , "hour"]
# [1] 16 17
See also Examples in the help text.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With