tl;dr
I keep opening more than one instance of the same RStudio Project and it’s annoying me, so I wrote a function to warn me on startup.
Double trouble
Sometimes I write code in an RStudio Project and then go and do something else. My memory is terrible, so later I might open a second instance of the same project and wonder what happened to that code I’d written before.
Is there a way to stop this from happening? Maybe there’s a setting in RStudio or something? Maybe I should just Google it?
Nah, instead I hacked together a little function that can be run on startup to warn me—via both text and audio—if I have multiple RStudio sessions open with the same name. It’s called check_rproj_dupes()
.
Note that the function checks which OS you’re using with .Platform$OS.type
, with the hope that one day I (or you) will write some corresponding code that will work on Windows. I don’t use Windows, so I can’t test anything.
The code has a few steps:
- Pass the
ps
(process status) command with flag-e
(show all running processes) to the shell via thesystem()
function, which is captured in a vector whenintern = TRUE
- Use
grepl()
to isolate the strings that contain the ‘.RProj’ RStudio Project extension - Extract the full paths to the .RProj files
- Extract the basenames from the paths (i.e. just the filename for the .RProj)
- Compare the basenames to see which are duplicated
- Display any matches in a warning message and, if
speak = TRUE
, read aloud a warning message that’s passed to thesay
function viasystem()
Yeah, this could be simplified, but I’m no code golfer. I just want it to work and for it to be pretty obvious what it’s doing.
Here it is (or see it in a GitHub Gist, where you can write your suggestions for how to improve it):
check_rproj_dupes <- function(speak = FALSE) {
os <- .Platform$OS.type
if (os == "unix") {
ps_out <- system("ps -e", intern = TRUE)
ps_rproj <- ps_out[grepl(".Rproj", ps_out)]
ps_split <- strsplit(ps_rproj, "\\s")
rproj_paths <- lapply(ps_split, function(x) x[grepl(".Rproj$", x)])
rproj_basenames <- lapply(rproj_paths, basename)
rproj_dupes <- sort(unlist(rproj_basenames[duplicated(rproj_basenames)]))
}
if (os == "windows") {
stop("Sorry, check_rproj_dupes() doesn't work on Windows yet :-(")
}
if (length(rproj_dupes) > 0) {
if (speak & os == "unix") {
dupes_string <- paste(rproj_dupes, collapse = ", ")
dupes_string_say <- gsub("\\.Rproj", " dot ar proj ", dupes_string)
message <- paste(
"say ha, you fool, you have more than one open RStudio Project with",
ifelse(length(rproj_dupes) == 1, "this name:", "these names:"),
dupes_string_say
)
system(message)
}
warning(
"You've got open RStudio Projects with the same name:\n",
paste("-", rproj_dupes, collapse = "\n"), "\n",
call. = FALSE
)
}
}
check_rproj_dupes()
rm(check_rproj_dupes)
How would you actually use this though?
You can add it to your ‘hidden’ .Rprofile file, which is a place that you can store code that runs whenever RStudio is started.1 Perhaps the easiest way to open it is with usethis::edit_r_profile()
. Then you can paste in all the code from the block above.2
On startup, the code will run and if there’s no problem, then you’ll see no message. No news is good news.
But let’s say I had opened sandbox.Rproj earlier and was now opening the file again. In this second RStudio instance, the usual R startup message will print, followed by a warning:
Warning message:
You've got open RStudio Projects with the same name:
- sandbox.Rproj
If speak = TRUE
then you’ll also hear this:
So hopefully now I will be less confused when trying to manage my RStudio sessions. At worst I’ll be shocked to hear the creepy computer voice tell me I’m a fool.
Session info
## ─ Session info ───────────────────────────────────────────────────────────────
## setting value
## version R version 4.2.0 (2022-04-22)
## os macOS Big Sur/Monterey 10.16
## system x86_64, darwin17.0
## ui X11
## language (EN)
## collate en_GB.UTF-8
## ctype en_GB.UTF-8
## tz Europe/London
## date 2022-08-10
## pandoc 2.18 @ /Applications/RStudio.app/Contents/MacOS/quarto/bin/tools/ (via rmarkdown)
##
## ─ Packages ───────────────────────────────────────────────────────────────────
## package * version date (UTC) lib source
## blogdown 1.9 2022-03-28 [1] CRAN (R 4.2.0)
## bookdown 0.26 2022-04-15 [1] CRAN (R 4.2.0)
## bslib 0.3.1 2021-10-06 [1] CRAN (R 4.2.0)
## cli 3.3.0 2022-04-25 [1] CRAN (R 4.2.0)
## digest 0.6.29 2021-12-01 [1] CRAN (R 4.2.0)
## evaluate 0.15 2022-02-18 [1] CRAN (R 4.2.0)
## fastmap 1.1.0 2021-01-25 [1] CRAN (R 4.2.0)
## htmltools 0.5.2 2021-08-25 [1] CRAN (R 4.2.0)
## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.2.0)
## jsonlite 1.8.0 2022-02-22 [1] CRAN (R 4.2.0)
## knitr 1.39 2022-04-26 [1] CRAN (R 4.2.0)
## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.2.0)
## R6 2.5.1 2021-08-19 [1] CRAN (R 4.2.0)
## rlang 1.0.2 2022-03-04 [1] CRAN (R 4.2.0)
## rmarkdown 2.14 2022-04-25 [1] CRAN (R 4.2.0)
## rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.2.0)
## sass 0.4.1 2022-03-23 [1] CRAN (R 4.2.0)
## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.2.0)
## stringi 1.7.6 2021-11-29 [1] CRAN (R 4.2.0)
## stringr 1.4.0 2019-02-10 [1] CRAN (R 4.2.0)
## xfun 0.30 2022-03-02 [1] CRAN (R 4.2.0)
## yaml 2.3.5 2022-02-21 [1] CRAN (R 4.2.0)
##
## [1] /Library/Frameworks/R.framework/Versions/4.2/Resources/library
##
## ──────────────────────────────────────────────────────────────────────────────
I tend not to put anything in here that would hamper reproducibility, i.e. another user shouldn’t have to run anything in my .Rprofile to be able to re-run my scripts on their computer.↩︎
The code is in a GitHub Gist too, so in theory you could pass the URL to the raw code to
source()
. But don’t do that because you shouldn’t trust me or anyone. And also it won’t work if you aren’t connected to the internet.↩︎