.Last() in .RProfile doesn't execute - r

I'm trying to make R restart on quit, so I'm using .Last in my .Rprofile.
Solution modified from Quit and restart a clean R session from within R?, and I've tried the other solutions in that answer to no avail.
my .First() works fine, but when I q() at the end, it prompts for "save workspace image?" and after answering, it insta-closes
.Last <- function()
{
print("new R in 3 seconds")
Sys.sleep(3)
system("R --no-save")
print("close R in 3 seconds")
Sys.sleep(3)
}
print("test")
(the print at the end is because there's a hidden "feature" where .Rprofile ignores the last line if theres no newline, I know it shouldn't execute that.)

Related

readline does not prompt user input from Rprofile.site in Rstudio

I have this little function in a file:
library(grDevices) # needed in Rprofile.site
readfun <- function()
{
message("interactive: ", interactive()) # tells TRUE
rl <- readline("Write something: ")
message("rl value is: ", rl)
}
readfun()
I can source it in the R console witin Rstudio just fine.
I can write source("thatfile.R") in the Rrofile.site and calling Rterm via R.exe prompts input as expected. (I'm on Windows, btw).
But starting R with Rstudio, it will not prompt for user input.
Instead, the first typed command will not be executed but messaged back.
This could be related to Wait for user input from keyboard in R before next line of code - readline - Rstudio, but I can't find a way to get it to work...

execute functions immediately when opening R

I was wondering how I can execute some pre-defined functions when I open R or R-studio?
I know that it sounds silly, but I installed package praise and sort of want to try executing praise() automatically every time I open R or R studio, without actually typing in praise().
For this you can use .First() and .Last() in the .Rprofile.
It's a typical R file, launched on startup and used primarly to export some stuff by default.
Example .Rprofile:
# .First() run at the start of every R session.
# Use to load commonly used packages?
.First <- function() {
library(ggplot2)
cat("\nSuccessfully loaded .Rprofile at", date(), "\n")
}
# .Last() run at the end of the session
.Last <- function() {
cat("\nGoodbye at ", date(), "\n")
}
Related: Expert R users, what's in your .Rprofile?

Clean last error in R

I would like to clean my current R session from the last error so that a next call to geterrmessage() will be empty.
Example:
> stop('halt !')
Error: halt !
> geterrmessage()
[1] "Error: halt !\n"
> something_that_cleans_the_last_error
> geterrmessage()
[1] ""
Thanks
Since there doesn't seem to be an easy to way to do this, here are some alternatives:
Start a new instance of R and quit the old one:
system("R"); q("no")
This will clear your workspace entirely. If you want to save your workspace, try:
save.image(); system("R"); q("no")
This restores your workspace, but will leave a lingering workspace file .Rdata. If you want to remove that as well:
save.image(); system("R"); unlink('.Rdata'); q("no");
But you will still have to reload any packages that you had previously loaded. That is, unless you do:
lp<-(.packages()); save.image(); system("R"); unlink('.Rdata'); q("no");
rapply(as.list(lp), library); rm(lp)
which only works from the command line, since the second line has to be entered into the new R shell.
Note: I don't actually recommend this solution.

Sink does not release file

I know that the sink() function can be used to divert R output into a file, e.g.
sink('sink-closing.txt')
cat('Hello world!')
sink()
Is there a simple command to close all outstanding sinks?
Below, I elaborate on my question.
Suppose that my R-script opens a sink() in an R-script, but there is an error in the R-script which occurs before the script closes the sink(). I may run the R-script multiple times, trying to fix the error. Finally, I want to close all the sinks and print to the console. How do I do so?
Finally, in the interest of concreteness, I provide a MWE to illustrate the problem I face.
First, I write an R-script sink-closing.R which has an error in it.
sink('sink-closing.txt')
foo <- function() {
cat(sprintf('Hello world! My name is %s\n',
a.variable.that.does.not.exist))
}
foo()
sink()
Next, I source the R-script multiple times, say 3 times by mistake as I try to find and fix the bug.
> source('~/Dropbox/cookbook/r-cookbook/sink-closing.R')
Error in sprintf("Hello world! My name is %s\n", a.variable.that.does.not.exist) :
object 'a.variable.that.does.not.exist' not found
Now, suppose that I am debugging the R-script and want to print to the console. I can call sink() multiple times to close the earlier sinks. If I call it 3 times, then I can finally print to the console as before. But how do I know how many sinks I need to close?
closeAllConnections() # .........................
I'm getting upvotes for this as time goes along but Simon.S.A and others are better.
You can use sink.number() to tell you how many diversions are already set and then call sink that many times. Putting it into a function you could have this
sink.reset <- function(){
for(i in seq_len(sink.number())){
sink(NULL)
}
}
Based on #mnel's comment:
sinkall <- function() {
i <- sink.number()
while (i > 0) {
sink()
i <- i - 1
}
}
Should close all open sinks.
You may also encounter this problem when dealing with devices and plots, where the number of open devices isn't reported anywhere. For a more general case you could use this:
stopWhenError <- function(FUN) {
tryCatch({
while(TRUE) {
FUN()
}
}, warning = function(w) {
print("All finished!")
}, error = function(e) {
print("All finished!")
})
}
stopWhenError(sink) # for sink.
stopWhenError(dev.off) # close all open plotting devices.
EDIT:
sink throws a warning not an error so I've modified the code so that it won't run forever, whoops!
The most common time I experience this is when an error occurs preventing a sink from closing. For example, the following will leave an open sink after execution.
sink("output.txt")
my_function_that_will_error()
sink()
This can be avoided using on.exit(sink()). This will close the sink "when the current function exits (either naturally or as the result of an error)" (documentation here).
But you do have to change the order:
sink("output.txt")
on.exit(sink())
my_function_that_might_error()
So we create the sink, tell R to close it when it exits, and then execute the code that might error. This will close the sink regardless of whether the code errors or not.

Difference between .Rprofile and .First

This might be straightforward, but I still feel frustrated, so I'd appreciate some quick explanation. I have extensively looked for a proper answer, but cannot seem to find one.
Since my .Rprofile includes all the commands that I need to run every time I open Rstudio (or R in general), why do I have the optionality to define the .First() function within the .Rprofile? What is it really the purpose of .First()?
To give an example, suppose that my .Rprofile has the following lines:
.First <- function(){
library(xts)
cat("\nWelcome at", date(), "\n")
}
How different is the above from simply having in my .Rprofile the lines:
library(xts)
cat("\nWelcome at", date(), "\n")
I have tried both and they do have the same outcome.
Thanks!
The main difference is that .First is executed after the default workspace image .Rdata (if it exists) is loaded, and so has access to objects in that workspace.
For example, let's create an object that will be automatically loaded on startup:
x <- 2
save.image()
Quit R, and create a .RProfile in your default working directory containing:
y <- try(print(x))
print(y)
.First <- function()
{
print(x)
invisible(NULL)
}
The first attempt to print x should fail, but the second should succeed.

Resources