R 对象创建时间戳

R 对象创建时间戳,r,object,timestamp,R,Object,Timestamp,有没有一种方法可以检索对象创建的时间?一般来说不是这样,但是您可以为自己创建的对象执行此操作 R> df <- data.frame(a=sample(LETTERS[1:5],10,TRUE),b=runif(10)) R> attr(df, "createdAt") <- Sys.time() R> df a b 1 B 0.8437021 2 D 0.8683446 3 B 0.5194791 4 B 0.0480405 5 B

有没有一种方法可以检索对象创建的时间?

一般来说不是这样,但是您可以为自己创建的对象执行此操作

R> df <- data.frame(a=sample(LETTERS[1:5],10,TRUE),b=runif(10))
R> attr(df, "createdAt") <- Sys.time()
R> df
   a         b
1  B 0.8437021
2  D 0.8683446
3  B 0.5194791
4  B 0.0480405
5  B 0.5604978
6  C 0.1938154
7  A 0.1451077
8  D 0.1785405
9  C 0.3937795
10 B 0.2874135
R> str(df)
'data.frame':   10 obs. of  2 variables:
 $ a: Factor w/ 4 levels "A","B","C","D": 2 4 2 2 2 3 1 4 3 2
 $ b: num  0.844 0.868 0.519 0.048 0.56 ...
 - attr(*, "createdAt")= POSIXct, format: "2011-03-16 10:42:10.137434"
R> 
R>df attr(df,“createdAt”)df
a b
1 B 0.8437021
2 D 0.8683446
3 B 0.5194791
4 B 0.0480405
5 B 0.5604978
6 C 0.1938154
7 A 0.1451077
8 D 0.1785405
9 C 0.3937795
10 B 0.2874135
R> str(df)
“data.frame”:10个obs。共有2个变量:
$a:系数w/4级“a”、“B”、“C”、“D”:2 4 3 2
$b:num 0.8440.8680.5190.0480.56。。。
-attr(*,“createdAt”)=POSIXct,格式:“2011-03-16 10:42:10.137434”
R>
然后,您可以编写一些使用该属性的自定义
print()
show()
函数。弗兰克·哈雷尔及其设计前辈已经做了很长一段时间了。

简短回答:没有


详细回答:是的,您所需要做的就是在R的C内核中重写赋值代码,以便在每次对象更改时在某处存储一个日期戳。我试过一次,将数据存储在一个属性中,就像这里的其他答案一样,但它有一个不幸的副作用,即使相同的对象不同。x=1和y=1有不同的时间戳,所以相同的(x,y)是错误的,这在很大程度上破坏了R的测试。我放弃了。

关于Spacedman的回答和我的评论,请参见以下示例:

x <- 1
print(x)
# [1] 1

`<-` = function(...) {
  eval.parent(replace(match.call(), c(1, 3), list(base::`<-`, structure(..2, ctime=Sys.time()))))
}

x <- 2
print(x)
# [1] 2
# attr(,"ctime")
# [1] "2011-03-17 11:33:55 EDT"

x我认为Charles的功能很棒,但它会在全球环境中制造问题

我建议创建一个新的操作符
%c%
来代替
xx%c%1
>xx
[1] 1
属性(,“ctime”)
[1] “2017-09-14 17:01:03星期一”
>xx+1
[1] 2
属性(,“ctime”)
[1] “2017-09-14 17:01:03星期一”
>班级(xx)
[1] “数字”
>yy%c%2
>xx+yy
[1] 3
属性(,“ctime”)
[1] “2017-09-14 17:01:03星期一”
>yy
[1] 2
属性(,“ctime”)
[1] “2017-09-14 17:04:27星期一”
>xx%c xx%c>%yy
[1] 假的

如果不改变对象,而是像保存历史一样保存时间戳,您认为如何?R将控制台历史记录保存到您正在使用的文件夹中的文件
.rhistore
(即
getwd()

我允许R将时间戳(Unix格式,自Epoch=1970年1月1日0:00:00起的秒数)保存到
.Rtimestamps
,但仅当此选项设置为:

#' @export
#' @noRd
`<-` = function(...) {
  if (!is.null(getOption("recordTimestamps"))
      & interactive()
      & environmentName(parent.frame()) == "R_GlobalEnv") {
    # only save timestamp when set in options, in interactive mode and in global env.
    if (getOption("recordTimestamps")) {
      write(
        x = paste(
          as.character(match.call())[2],
          as.double(Sys.time()),
          sep = ","),
        file = ".Rtimestamps",
        append = TRUE)
    }
  }
  eval.parent(
    replace(
      match.call(),
      1,
      list(base::`<-`)))
}

在邮件列表中有一个类似的问题,您仍然可以在本地(即在给定的环境中)执行此操作,只需覆盖
Hmm,这似乎很有趣。我想知道是否可以将时间戳存储在不同的对象中,而不是作为对象本身的属性,例如,存储在哈希表中(通过我的新朋友
hash
)。谢谢。我自己在这个方向上尝试了一些东西,但运气不好。
> xx %c% 1
> xx
[1] 1
attr(,"ctime")
[1] "2017-09-14 17:01:03 EEST"
> xx + 1
[1] 2
attr(,"ctime")
[1] "2017-09-14 17:01:03 EEST"
> class(xx)
[1] "numeric"
> yy %c% 2
> xx+yy
[1] 3
attr(,"ctime")
[1] "2017-09-14 17:01:03 EEST"
> yy
[1] 2
attr(,"ctime")
[1] "2017-09-14 17:04:27 EEST"
> xx %c<% yy
[1] TRUE
> xx %c>% yy
[1] FALSE
#' @export
#' @noRd
`<-` = function(...) {
  if (!is.null(getOption("recordTimestamps"))
      & interactive()
      & environmentName(parent.frame()) == "R_GlobalEnv") {
    # only save timestamp when set in options, in interactive mode and in global env.
    if (getOption("recordTimestamps")) {
      write(
        x = paste(
          as.character(match.call())[2],
          as.double(Sys.time()),
          sep = ","),
        file = ".Rtimestamps",
        append = TRUE)
    }
  }
  eval.parent(
    replace(
      match.call(),
      1,
      list(base::`<-`)))
}
options(recordTimestamps = TRUE) # only first time of course
a <- 123
# wait 5 seconds and change it
a <- 456
#' @export
#' @noRd
ctime <- function(object) {
  target_object <- deparse(substitute(object))
  get_cmtime(target_object, 1)
}

#' @export
#' @noRd
mtime <- function(object) {
  target_object <- deparse(substitute(object))
  get_cmtime(target_object, 2)
}

get_cmtime <- function(target_object, mode) {
  if (!is.null(getOption("recordTimestamps")) & interactive()) {
    # only get dates when set in options and when in interactive mode
    if (getOption("recordTimestamps") & file.exists(".Rtimestamps")) {
      lines <- readLines(con <- file(".Rtimestamps"), warn = FALSE, encoding = "UTF-8")
      close(con)
      target_lines <- lines[grepl(paste0("^(", target_object, "),"), lines)]
      if (length(target_lines) > 0) {
        if (mode == 1) {
          # get first value, second element
          timestamp <- unlist(strsplit(target_lines[1], ","))[2]
        } else if (mode == 2) {
          # get last value, second element
          timestamp <- unlist(strsplit(target_lines[length(target_lines)], ","))[2]
        }
        ## transform to date
        return(as.POSIXct(origin = "1970-01-01", x = as.double(timestamp)))
      } else {
        return(NA)
      }
    }
  }
}
> a
[1] 456
> ctime(a)
[1] "2018-02-07 10:43:03 CET"
> mtime(a)
[1] "2018-02-07 10:43:08 CET"