6

当一个计算系统停机/忙碌时,我经常发现自己将工作空间转移到不同的暂存驱动器等,或者,我想同时运行两个冗长的包以节省时间并在不同的地方两次加载相同的工作空间。

正因为如此,我真的很喜欢一种查看工作区之间不同对象的方法以及一种组合它们的方法,只将新的、更改的或更新的工作区对象添加到类似的工作区。这对我来说非常有用。

到目前为止,我依赖于手动记笔记,并且在两周后对我的涂鸦感到困惑。我真的只是想学习如此好的工作实践和习惯,让这种事情变得更容易。

一般来说,我真的很想了解更多关于工作空间管理的信息,以及有经验的用户如何为长期、持续的项目保持工作空间的全面和整洁。我经常使用 Rstudio,但远程工作或使用我们的 HPC 系统可能有点滞后和笨拙,所以我倾向于使用命令行和交互式会话。

我认为制作对象列表可能是关键,但我希望能够更轻松地注释事物,也许使用用于制作对象的数据和参数等。

谢谢。

4

3 回答 3

4

我认为需要在这里构建自己的功能,执行以下操作:

  • 一个接一个地加载工作区,使用:

    load()
    
  • 重命名工作区的每个元素以防止在加载另一个工作区或将其放入列表时覆盖

  • 检查工作区的时间戳:

    file.info()
    
  • 并仅保留最新的对象,然后将其保存在一些最新的工作区中

例子:

for(i in 1:10){
    dummy <- rnorm(1)
    Sys.sleep(1.3)
    save(dummy,file=paste("test",i,".Rdata",sep=""))
}

DUMMY <- list()
timestamps <- NULL

for(i in 1:10){
    filename <- paste("test",i,".Rdata",sep="")
    load(filename)
    DUMMY[[i]] <- dummy
    timestamps[i] <- file.info(filename)$mtime
}

uptodate <- unlist(timestamps)==max(unlist(timestamps))
dummy <- unlist(DUMMY[uptodate])
save(dummy,file="uptodate.Rdata")
于 2012-10-06T15:03:01.633 回答
3

我认为关键是将您的工作区加载到单独的环境中,然后弄清楚您希望如何合并它们(如果有的话)。

首先,让我们制作一些要保存的对象。

set.seed(1)
a <- data.frame(1:10, 1:10)
b <- rnorm(10)

跟踪对象创建时间的一种方法是设置属性。缺点是您必须记住在更新对象时更新它。(有关替代方案,请参阅帖子的最后一部分)

d <- structure(data.frame(b), updated=Sys.time())
attr(d, 'updated')
#[1] "2012-10-06 12:34:06 CDT"

您可以在保存工作空间之前将当前时间分配给一个变量,以了解您何时保存它(PeterMfile.info建议可能是更好的选择)

updated <- Sys.time() 
dir.create('~/tmp') # create a directory to save workspace in.
save.image('~/tmp/ws1.RData')

d[1, 1] <- 1 #make a change to `d`
attr(d, "updated") <- Sys.time() # don't forget to update the `updated` attribute
e <- b * a # add a new object
updated <- Sys.time()
save.image('~/tmp/ws2.RData')

现在清除工作区,并加载工作区。但是,不是将它们加载到 中,而是将它们.GlobalEnv加载到自己的环境中

rm(list=ls(all=TRUE)) # clear .GlobalEnv
w1 <- new.env()
w2 <- new.env()
load('~/tmp/ws1.RData', envir=w1)
load('~/tmp/ws2.RData', envir=w2)

> ls(w1)
[1] "a"       "b"       "d"       "updated"
> ls(w2)
[1] "a"       "b"       "d"       "e"       "updated"

> with(w1, updated)
[1] "2012-10-06 12:34:09 CDT"
> with(w2, updated)
[1] "2012-10-06 12:35:02 CDT"

> attr(w1$d, 'updated')
[1] "2012-10-06 12:34:06 CDT"
> attr(w2$d, 'updated')
[1] "2012-10-06 12:35:02 CDT"

您可能对类似的功能感兴趣.ls.objects

> .ls.objects(pos=w1)
              Type Size PrettySize Rows Columns
a       data.frame  872    [1] 872   10       2
b          numeric  168    [1] 168   10      NA
d       data.frame 1224   [1] 1224   10       1
updated    POSIXct  312    [1] 312    1      NA
> .ls.objects(pos=w2)
              Type Size PrettySize Rows Columns
a       data.frame  872    [1] 872   10       2
b          numeric  168    [1] 168   10      NA
d       data.frame 1224   [1] 1224   10       1
e       data.frame 1032   [1] 1032   10       2
updated    POSIXct  312    [1] 312    1      NA

您可以使用自定义包装器assign来跟踪对象的更新时间。

myAssign <- function(x, value, ...) {
  attr(value, "updated") <- Sys.time()
  assign(x, value, ...)
}

> myAssign("b", w1$b[1:2], pos=w1)
> w1$b
[1] -0.6264538  0.1836433
attr(,"updated")
[1] "2012-10-06 12:44:55 CDT"

最后,如果你想变得花哨,你可以做一个主动绑定,这样你的对象updated在它改变时总是得到一个更新的属性。

f <- local({
  delayedAssign('x', stop('object not found'))
  function(v) {
    if (!missing(v)) x <<- structure(v, updated=Sys.time())
    x
  }
})
makeActiveBinding('ab', f, .GlobalEnv)
> ab # Error, nothing has been assigned to it yet
Error in function (v)  : object not found
> ab <- data.frame(1:10, y=rnorm(10))
> attr(ab, 'updated')
[1] "2012-10-06 12:46:53 CDT"
> ab <- data.frame(10:1, y=rnorm(10))
> attr(ab, 'updated')
[1] "2012-10-06 12:47:04 CDT"
于 2012-10-06T17:54:55.757 回答
1

我可以回答您的部分问题,但将其余问题留给其他人。

假设您的工作区有许多对象,在您退出 R 之前,保存工作区并将其重命名为 .RData 为 work1.RData。如果您使用的是 linux,请尝试重命名您的文件:

mv .RData work1.RData

然后您打开一个新的 R 会话,创建任意数量的对象并像以前一样保存它。如果您想将此工作区带到其他系统,您可以重命名它。

现在您有两个工作区 .RData 二进制文件。您可以使用将它们加载到单个当前工作区中

load ("work1.RData")

然后,像这样检查工作区中加载的对象

 ls() 
 objects()

在这种情况下也save.image()很有用。

高温高压

于 2012-10-06T15:07:02.430 回答