【问题标题】:Environment variables within a function函数内的环境变量
【发布时间】:2015-10-07 10:27:25
【问题描述】:

我试图在我正在使用的函数中获得一致的结果。但是,由于数组不记得时区信息,这比我预期的要难。

> 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] ""

如您所见,该数组删除了时区信息。这很烦人,因为 lubridate 的 day() 等其他函数会根据此时区信息改变行为。

因此我尝试了以下实验:

> 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"

事实证明,它仅在您在 return 语句之前重置时区时才有效。

有没有一种快速的方法可以只在函数内设置环境变量,而不读取当前变量并在每次返回之前重置它?

【问题讨论】:

  • return 语句之后的所有内容都不会执行。只需反转函数中行的顺序即可。或者使用on.exit(),这个函数可以让你在退出函数之前执行一个表达式。
  • on.exit() 真的很有用!感谢那。问题是我有多次退货,我不想重复 10 次,有可能在某处忘记它。
  • 你的意思是multiple returns?在 R 中,一个函数只能返回一个对象。如果你想要多个条件,你可以把on.exit()放在函数的顶部,不管函数退出的点,它都会被执行。
  • 是的,我就是这个意思。 if-else 构造,如果为真则返回一个值,如果为假则返回另一个值。这将产生两次回报,因此也是 Sys.setenv 的两倍。我认为 on.exit 是一个很好的方法。

标签: arrays r variables timezone environment


【解决方案1】:

我认为您需要阅读一些介绍性的 R 材料以及您正在使用的功能的帮助。

ISOdate()不使用环境变量'TZ'来选择时区:

> Sys.getenv('TZ')
[1] ""
> Sys.timezone(location=FALSE)
[1] "BST"
> ISOdate(2015, 1, 1, 1)
[1] "2015-01-01 01:00:00 GMT"

ISOdate() 产生一个带有tzone 属性的日期时间对象:

> attributes(ISOdate(2015,1,1,1))
$class
[1] "POSIXct" "POSIXt" 

$tzone
[1] "GMT"

我不认识tz() 函数,我认为它不在base 中。

在 R 中,向量(例如 1:3)不是数组:

> is.array(1:3)
[1] FALSE

c() 结合了它的参数,但(来自帮助)“有时用于删除除名称之外的属性的副作用”。通过将ISOdate() 包裹在c() 中,您已经删除了时区信息。

如果你想要一个日期向量,那么你也可以笨拙地使用c() 创建向量,然后再放回属性:

> 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"

...或者更好,使用ISOdate() 直接从参数向量生成日期对象向量:

> 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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 2022-12-14
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    相关资源
    最近更新 更多