Stop opening the same RStudio Project twice

An RStudio console on startup. After the usual R startup text it says 'Warning message: You've got open RStudio Projects with the same name' followed by a bullet point that says 'sandbox.Rproj'. Overlaid is the macOS item switcher showing that there are indeed two RStudio instances open with that name.

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:

  1. Pass the ps (process status) command with flag -e (show all running processes) to the shell via the system() function, which is captured in a vector when intern = TRUE
  2. Use grepl() to isolate the strings that contain the ‘.RProj’ RStudio Project extension
  3. Extract the full paths to the .RProj files
  4. Extract the basenames from the paths (i.e. just the filename for the .RProj)
  5. Compare the basenames to see which are duplicated
  6. Display any matches in a warning message and, if speak = TRUE, read aloud a warning message that’s passed to the say function via system()

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
## 
## ──────────────────────────────────────────────────────────────────────────────

  1. 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.↩︎

  2. 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.↩︎