I want to convert a numeric variable to POSIXct
using anytime
. My issue is that anytime(<numeric>)
converts the input variable as well - I want to keep it.
Simple example:
library(anytime)
t_num <- 1529734500
anytime(t_num)
# [1] "2018-06-23 08:15:00 CEST"
t_num
# [1] "2018-06-23 08:15:00 CEST"
This differs from the 'non-update by reference' behaviour of as.POSIXct
in base
R:
t_num <- 1529734500
as.POSIXct(t_num, origin = "1970-01-01")
# [1] "2018-06-23 08:15:00 CEST"
t_num
# 1529734500
Similarly, anydate(<numeric>)
also updates by reference:
d_num <- 17707
anydate(d_num)
# [1] "2018-06-25"
d_num
# [1] "2018-06-25"
I can't find an explicit description of this behaviour in ?anytime
. I could use as.POSIXct
as above, but does anyone know how to handle this within anytime
?
anytime
author here: this is standard R and Rcpp and passing-by-SEXP
behaviour: you cannot protect a SEXP
being passed from being changed.
The view that anytime
takes is that you are asking for an input to be converted to a POSIXct
as that is what anytime
does: from char, from int, from factor, from anything. As a POSIXct
really is a numeric value (plus a S3 class attribute) this is what you are getting.
If you do not want this (counter to the design of anytime
) you can do what @Moody_Mudskipper and @PKumar showed: used a temporary expression (or variable).
(I also think the data.table
example is a little unfair as data.table
-- just like Rcpp
-- is very explicit about taking references where it can. So of course it refers back to the original variable. There are idioms for deep copy if you need them.)
Lastly, an obvious trick is to use format
if you just want different display:
R> d <- data.frame(t_num=1529734500)
R> d[1, "posixct"] <- format(anytime::anytime(d[1, "t_num"]))
R> d
t_num posixct
1 1529734500 2018-06-23 01:15:00
R>
That would work the same way in data.table
, of course, as the string representation is a type change. Ditto for IDate
/ ITime
.
Edit: And the development version in the Github repo has had functionality to preserve the incoming argument since June 2017. So the next CRAN version, whenever I will push it, will have it too.
You could hack it like this:
library(anytime)
t_num <- 1529734500
anytime(t_num+0)
# POSIXct[1:1], format: "2018-06-23 08:15:00"
t_num
# [1] 1529734500
Note that an integer input will be treated differently:
t_int <- 1529734500L
anytime(t_int)
# POSIXct[1:1], format: "2018-06-23 08:15:00"
t_int
# [1] 1529734500
If you do this, it will work :
t_num <- 1529734500
anytime(t_num*1)
#> anytime(t_num*1)
#[1] "2018-06-23 06:15:00 UTC"
#> t_num
#[1] 1529734500
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