问题
I am trying to have consistent results within a function that I am using. However, since an array does not remember timezone info, this is a little harder than I expected.
> Sys.setenv(TZ = "")
> ISOdate(2015,1,1,1,tz='UTC')
[1] "2015-01-01 01:00:00 UTC"
> c(ISOdate(2015,1,1,1,tz='UTC'))
[1] "2015-01-01 02:00:00 CET"
> tz(c(ISOdate(2015,1,1,1,tz='UTC')))
[1] ""
As you can see, the array drops the timezone information. This is annoying since other functions like day() of lubridate change behaviour depending on this timezone information.
Therefore I tried the following experiment:
> Sys.setenv(TZ = "")
> Sys.getenv('TZ')
[1] ""
> x <- function(){
used_timezone <- Sys.getenv('TZ')
Sys.setenv(TZ = "UTC")
return(5)
Sys.setenv(TZ = used_timezone)
}
> Sys.getenv('TZ')
[1] ""
> x()
[1] 5
> Sys.getenv('TZ')
[1] "UTC"
Turns out, it only works if you reset the timezone before the return statement.
Is there a quick way to set an environment variable only within a function without reading the current one and resetting it just before every return?
回答1:
I think you need to read some introductory R material and the help on the functions you are using.
ISOdate()
does not use the environment variable 'TZ' to choose time zone:
> Sys.getenv('TZ')
[1] ""
> Sys.timezone(location=FALSE)
[1] "BST"
> ISOdate(2015, 1, 1, 1)
[1] "2015-01-01 01:00:00 GMT"
ISOdate()
produces a date-time object with an attribute tzone
:
> attributes(ISOdate(2015,1,1,1))
$class
[1] "POSIXct" "POSIXt"
$tzone
[1] "GMT"
I don't recognize the tz()
function, I don't think it is in base
.
In R a vector (e.g. 1:3
) is not an array:
> is.array(1:3)
[1] FALSE
c()
combines its arguments but (from the help) "is sometimes used for its side effect of removing attributes except names". By wrapping ISOdate()
in c()
you have removed the time zone information.
If you want a vector of dates then you could either, clumsily use c()
to create the vector then put the attribute back again:
> aDate <- ISOdate(2015,1,1,1, tz="cet")
> aZone <- attr(aDate, "tzone")
> aObj <- c(aDate)
> aObj
[1] "2015-01-01 GMT"
> attr(aObj, "tzone") <- aZone
> aObj
[1] "2015-01-01 01:00:00 CET"
... or better, use ISOdate()
to produce a vector of date objects directly from vector(s) of arguments:
> ISOdate(2015, 1, 1:3, tz='cet')
[1] "2015-01-01 12:00:00 CET" "2015-01-02 12:00:00 CET"
[3] "2015-01-03 12:00:00 CET"
来源:https://stackoverflow.com/questions/32989821/environment-variables-within-a-function