在不中断for循环的情况下重新启动R会话

在不中断for循环的情况下重新启动R会话,r,R,在for循环中,我需要移除RAM。因此,我使用rm()命令删除了一些对象。然后,我做了gc(),但是RAM仍然是一样的 因此,我使用了.rs.restartR()而不是gc(),它可以工作:在R会话重新启动后,我的RAM的足够部分被移除 我的问题是for循环,它在R重新启动后被中断。在执行.rs.restartR()命令后,您是否有办法自动执行for循环 有没有办法在.rs.restartR()命令之后自动执行for循环 这是不可能的 好的,你可以配置你的R系统来做这样的事情,但这听起来是个坏

在for循环中,我需要移除RAM。因此,我使用
rm()
命令删除了一些对象。然后,我做了gc(),但是RAM仍然是一样的

因此,我使用了
.rs.restartR()
而不是
gc()
,它可以工作:在R会话重新启动后,我的RAM的足够部分被移除

我的问题是for循环,它在R重新启动后被中断。在执行
.rs.restartR()
命令后,您是否有办法自动执行for循环

有没有办法在.rs.restartR()命令之后自动执行for循环

这是不可能的


好的,你可以配置你的R系统来做这样的事情,但这听起来是个坏主意。我不确定您是想从头开始重新启动
for
循环,还是从停止的地方重新开始。(我也很困惑,在执行
for
循环时,您似乎能够在R控制台中输入命令。我想还有很多事情您没有告诉我们。)

您可以使用
rprofile.site
文件在R启动时自动运行命令。您可以将其设置为在R启动时自动运行for循环代码。但这似乎是个坏主意。我认为你应该为你的问题找到一种不同的解决方法

您可以做一些事情来帮助解决这种情况:让您的
for
将每次迭代的输出循环写入磁盘,并将某种日志写入磁盘,这样您就可以知道从哪里开始了。也许围绕for循环编写一个函数,该函数包含一个从何处开始的参数,这样您就可以在任何时候“跳入”

使用这种方法,而不是“重新启动R并自动拾取循环”,更好的选择是使用Rscript(或类似)并使用R或命令行在其自己的R会话中顺序运行每个迭代(或一批迭代)


最好的解决方法是在不重新启动的情况下解决内存问题。关于内存管理,这里有几个问题——试一下答案,如果答案不起作用,做一个重复的例子,然后问一个新问题

我只是偶然发现了这篇文章,因为我遇到了与rm()类似的问题,没有按预期清除内存。与您一样,如果我终止脚本,使用rm(list=ls(all.names=TRUE))删除所有内容并重新启动,那么脚本将比最初花费更长的时间。但是,使用.rs.restartR()重新启动会话,然后再次进行寻源,效果与预期一样。正如您所说,在循环中无法“刷新”会话

我的解决方案是编写一个简单的bash脚本来调用我的.r文件

假设在R中有一个从1到3运行的循环,并且希望在每次迭代后重新启动会话。我的bash脚本“runR.sh”可以如下所示:

  #!/bin/bash        

    for i in {1..3}
    do
      echo "Rscript myRcode.r $i" #check call to r script is as expected
      Rscript myRcode.r $i
    done
然后在“myRcode.r”的顶部:

args <- commandArgs()
print(args) #list the command line arguments. 

myvar <- as.numeric(args[6])

args您可以在重新启动会话后通过寻源使脚本递归

确保脚本将考虑循环的初始状态。因此,在重新启动会话之前,您可能必须将循环的当前状态保存在.rds文件中。然后在重新启动会话后从循环内部调用.rds文件。这将帮助您在重新启动r会话之前启动循环

我刚刚发现这个命令“restartSession”。我使用它是因为我也遇到了内存消耗问题,因为垃圾收集器不会将RAM返回给操作系统(Linux)


通过将迭代保存为外部文件,并编写一个调用自身的rscript,可以从rstudio中的for循环中重新启动会话。此示例需要以下步骤

#Save an the iteration as a separate .RData file in the working directory. 

iter <- 1

save(iter, file="iter.RData")
#在工作目录中将迭代另存为单独的.RData文件。

iter一种独立于Rstudio的方法: 如果您想在Rstudio中运行此功能,请不要使用R控制台,而要使用终端,否则请使用
rstudioapi::restartSession()
与其他答案中的一样-不推荐(崩溃)-

  • 创建迭代器并加载脚本(系统中的终端为:)

  • Script.R文件:

    # read files and iterator
    i<-readRDS("i.rds")
    print(i)
    
    # open process id of previous loop to kill it
    tryCatch(pid <- readRDS(file="pid.rds"), error=function(e){NA} )
    
    if (exists("pid")){
      library(tools)
      tools::pskill(pid, SIGKILL) 
    }
    
    # update objects and iterator
    i <- i+1
    # process
    pid <- Sys.getpid() 
    
    # save files and iterator
    saveRDS(i, file="i.rds")
    # process ID to close it in next loop
    saveRDS(pid, file="pid.rds")
    
    ### restart session calling the script again
    if(i <= 20 ) {
      print(paste("Processing of", i-1,"ended, restarting") )
      assign('.Last',  function() {system('Rscript Script.R')} )
      q(save = 'no')
    } 
    
    #读取文件和迭代器
    
    这完全取决于
    for
    循环中的内容。如果您有一种“保存状态”的方法(即使是周期性的,也不一定是每个循环),那么您可以在重新启动时选择它停止的位置。这当然是手动重启(正如@Gregor所说,这不会发生),但至少你可以保留工作,你可以。正如您所建议的,它充其量是非传统的,更可能是脆弱的/混乱的。这对我来说很有效,只需添加一个小的内容,即需要修改bash脚本,使其可以通过
    chmod 755 runR.sh
    执行。此外,为了避免每次运行都重新启动R,我在'seq 1100 1000`
    中将bash序列更改为step by 100,然后在R中运行循环100次。这会定期清除R中的内存,但避免了每次运行时重新加载库的开销。
    ###load iteration
    library(rstudioapi)
    
    load("iter.RData")
    
    ###insert function here.
    time_now <- Sys.time()
    
    ###save output of function to a file.
    save(time_now, file=paste0("time_", iter, ".Rdata"))
    
    ###update iteration
    iter <- iter+1
    save(iter, file="iter.RData")
    
    ###restart session calling the script again
    if(iter < 5){
    restartSession(command='source("test_script.R")')
    }
    
    R -e 'saveRDS(1,"i.rds"); source("Script.R")'
    
    # read files and iterator
    i<-readRDS("i.rds")
    print(i)
    
    # open process id of previous loop to kill it
    tryCatch(pid <- readRDS(file="pid.rds"), error=function(e){NA} )
    
    if (exists("pid")){
      library(tools)
      tools::pskill(pid, SIGKILL) 
    }
    
    # update objects and iterator
    i <- i+1
    # process
    pid <- Sys.getpid() 
    
    # save files and iterator
    saveRDS(i, file="i.rds")
    # process ID to close it in next loop
    saveRDS(pid, file="pid.rds")
    
    ### restart session calling the script again
    if(i <= 20 ) {
      print(paste("Processing of", i-1,"ended, restarting") )
      assign('.Last',  function() {system('Rscript Script.R')} )
      q(save = 'no')
    }