R command for setting working directory to source file location in Rstudio
Asked Answered
R

18

188

I am working out some tutorials in R. Each R code is contained in a specific folder. There are data files and other files in there. I want to open the .r file and source it such that I do not have to change the working directory in Rstudio as shown below:

enter image description here

Is there a way to specify my working directory automatically in R.

Repine answered 2/12, 2012 at 19:10 Comment(4)
This is probably a dupe. see ?setwd ?getwdNelda
https://mcmap.net/q/101731/-getting-path-of-an-r-scriptAfterheat
Not a dupe, the poster wants to load .rdata-files in the same folder, not source with the working directory set to the path of the sourced file.Selfliquidating
why is R making this so hard?Otolith
B
142

To get the location of a script being sourced, you can use utils::getSrcDirectory or utils::getSrcFilename. These require a function as an input. Create a script with the following lines, and source it to see their usage:

print(utils::getSrcDirectory(function(){}))
print(utils::getSrcFilename(function(){}, full.names = TRUE))

Changing the working directory to that of the current file can be done with:

setwd(getSrcDirectory(function(){})[1])

This does not work in RStudio if you Run the code rather than Sourceing it. For that, you need to use rstudioapi::getActiveDocumentContext.

setwd(dirname(rstudioapi::getActiveDocumentContext()$path))

This second solution requires that you are using RStudio as your IDE, of course.

Boudreau answered 7/3, 2016 at 11:6 Comment(15)
your own answer at https://mcmap.net/q/101731/-getting-path-of-an-r-script works (one must include the dirname though). I added itRepine
Doesn't work for me. I get Error: 'getActiveDocumentContext' is not an exported object from 'namespace:rstudioapi'Lomasi
@Lomasi are you using a recent version of RStudio? It won't work in other IDEs (including RGUI) or old versions of RStudio. Similarly, make sure you have the latest version of the rstudioapi package.Boudreau
Note that when you run getActiveDocumentContext() in the console within RStudio, the path is reported as ''. However, if you run the line of code in the editor portion, it will execute as expected. This may address @Lomasi 's commentManzano
I run setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) on a Mac and I got Error: 'getActiveDocumentContext' is not an exported object from 'namespace:rstudioapi'Otolith
@giac_man It sounds like you are using a very old version of the rstudioapi package. Try updating to the latest one.Boudreau
I get: Error in setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) : cannot change working directory; Apparently because I run it in the console. It runs well in the script.Desrosiers
@SanduUrsu Correct: the console is not an active document, so rstudioapi::getActiveDocumentContext()$path is "".Boudreau
setwd(getSrcDirectory()[1]) didn't work for me when I sourced the file. The rstudioapi solution worked.Towery
@RichieCotton is there a way to automatically jump to that working directory and showing it content in 'Files' tab in RStudio?Wendling
@Wendling At the top of the console, you should see the current working directory. To the right of that is a small arrow. Click that to show the current working directory in the file browser.Boudreau
@RichieCotton, yes, nice feature I didn't know about, thanks. But if I have multiple scripts open in the Source window its name is displayed only after I ran one (and then I still have to click on the arrow). It would be best the Files view switches automatically to that of the viewed script.Wendling
getSrcDirectory() does not work as it needs an object or function as input.Licentious
@Towery @SimonChemnitz-Thomsen Note that you can use the following trick in order to get the script directory using utils::getSrcDirectory(). First thing you do in the script is to define a dummy function, then call utils::getSrcDirectory() using that function as parameter. Ex: dummy = function() {}; scriptdir = utils::getSrcDirectory(dummy); rm(dummy)Diapophysis
@RichieCotton I thought you may want to edit your answer so that using utils::getSrcDirectory() actually works to retrieve the script directory...? The trick is to define a dummy function in the script as I describe in the comment I just posted.Diapophysis
E
67

I know this question is outdated, but I was searching for a solution for that as well and Google lists this at the very top:

this.dir <- dirname(parent.frame(2)$ofile)
setwd(this.dir)

put that somewhere into the file (best would be the beginning, though), so that the wd is changed according to that file.

According to the comments, this might not necessarily work on every platform (Windows seems to work, Linux/Mac for some). Keep in mind that this solution is for 'sourcing' the files, not necessarily for running chunks in that file.

see also get filename and path of `source`d file

Easel answered 23/9, 2014 at 13:9 Comment(9)
didn't work for me either: Error in dirname(parent.frame(2)$ofile) : a character vector argument expectedGenevivegenevra
did you look in the linked thread as well? I don't know any solution by now, but there are other people with similar errors. Maybe it is OS-specific? I used it on Windows 8, but some report it didn't work on mac ...Easel
Same problem here as @Matt O'Brien on Linux.Compliment
running on windows, same proble here as @bisounours_tronconneuseEnquire
Working perfectly if sourced.Galop
Worked for me in RStudio v1.0.143 on Windows 10. If you select "Source on save", it will work just fine (you can print out the detected directory with "cat"). If you select the lines then execute them, then the result is null.Balcer
@Easel I think this answer should be edited based on these comments: mention that this works for windows and is not tested for other OS. Thanks.Alfaro
This works for me on a Mac when sourcing a file. However, as @Balcer pointed out above, it will not work when executing the code interactively by highlighting a chunk and pressing Command + Return. In this case, since you're not sourcing a file, there is no source file to pull the working directory from. The answer need not specify platform-specific caveats.Know
@MrSCoder Do you have any error message or alike? Maybe the solution is already outdated. Did you try another solution here?Easel
E
16

For rstudio, you can automatically set your working directory to the script directory using rstudioapi like that:

library(rstudioapi)

# Getting the path of your current open file
current_path = rstudioapi::getActiveDocumentContext()$path 
setwd(dirname(current_path ))
print( getwd() )

This works when Running or Sourceing your file.

You need to install the package rstudioapi first. Notice I print the path to be 100% sure I'm at the right place, but this is optional.

Engel answered 10/5, 2018 at 20:49 Comment(3)
Error in setwd(dirname(current_path)) : cannot change working directoryAlfaro
@helmo check your user has write permission on the target directory.Engel
unfortunately "rstudioapi::getActiveDocumentContext()$path" gives me an empty stringOtolith
N
8
dirname(rstudioapi::getActiveDocumentContext()$path)

works for me but if you don't want to use rstudioapi and you are not in a proyect, you can use the symbol ~ in your path. The symbol ~ refers to the default RStudio working directory (at least on Windows).

RStudio options

If your RStudio working directory is "D:/Documents", setwd("~/proyect1") is the same as setwd("D:/Documents/proyect1").

Once you set that, you can navigate to a subdirectory: read.csv("DATA/mydata.csv"). Is the same as read.csv("D:/Documents/proyect1/DATA/mydata.csv").

If you want to navigate to a parent folder, you can use "../". For example: read.csv("../olddata/DATA/mydata.csv") which is the same as read.csv("D:/Documents/oldata/DATA/mydata.csv")

This is the best way for me to code scripts, no matter what computer you are using.

Neal answered 2/12, 2016 at 13:1 Comment(0)
S
8
setwd(this.path::here())

works both for sourced and "active" scripts.

Smoulder answered 30/11, 2022 at 11:2 Comment(3)
I get "Error in loadNamespace(x) : there is no package called ‘this.path’" - what am I missing?Otolith
You have to install the package before, you can do this by launching install.packages("this.path")Smoulder
I confirm that this works. It is the simplest among all answers.Preserve
D
7

I realize that this is an old thread, but I had a similar problem with needing to set the working directory and couldn't get any of the solutions to work for me. Here's what did work, in case anyone else stumbles across this later on:

# SET WORKING DIRECTORY TO CURRENT DIRECTORY:
system("pwd=`pwd`; $pwd 2> dummyfile.txt")
dir <- fread("dummyfile.txt")
n<- colnames(dir)[2]
n2 <- substr(n, 1, nchar(n)-1)
setwd(n2)

It's a bit convoluted, but basically this uses system commands to get the working directory and save it to dummyfile.txt, then R reads that file using data.table::fread. The rest is just cleaning up what got printed to the file so that I'm left with just the directory path.

I needed to run R on a cluster, so there was no way to know what directory I'd end up in (jobs get assigned a number and a compute node). This did the trick for me.

Docilla answered 2/6, 2017 at 22:52 Comment(0)
C
6

This answer can help:

script.dir <- dirname(sys.frame(1)$ofile)

Note: script must be sourced in order to return correct path

I found it in: https://support.rstudio.com/hc/communities/public/questions/200895567-can-user-obtain-the-path-of-current-Project-s-directory-

The BumbleBee´s answer (with parent.frame instead sys.frame) didn´t work to me, I always get an error.

Cuprum answered 25/4, 2015 at 22:39 Comment(0)
I
6

The here package provides the here() function, which returns your project root directory based on some heuristics.

Not the perfect solution, since it doesn't find the location of the script, but it suffices for some purposes so I thought I'd put it here.

Ibadan answered 28/8, 2019 at 20:24 Comment(2)
Thanks for this answer. The location of the current script can be harnessed by placing a call to here::set_here() in the source.Pasto
When run in RStudio with project setup, here::here() returns the project working directory, not the script location. this.path::here() works regardless of project setup.Preserve
R
5

The solution

dirname(parent.frame(2)$ofile)

not working for me.

I'm using a brute force algorithm, but works:

File <- "filename"
Files <- list.files(path=file.path("~"),recursive=T,include.dirs=T)
Path.file <- names(unlist(sapply(Files,grep,pattern=File))[1])
Dir.wd <- dirname(Path.file)

More easy when searching a directory:

Dirname <- "subdir_name"
Dirs <- list.dirs(path=file.path("~"),recursive=T)
dir_wd <- names(unlist(sapply(Dirs,grep,pattern=Dirname))[1])
Robbins answered 21/11, 2014 at 9:23 Comment(1)
Problem with this solution is that is very slow. Searching for all files and store in a variable also takes up a lot of memory.Alfaro
N
5

If you work on Linux you can try this:

setwd(system("pwd", intern = T) )

It works for me.

Naphthol answered 1/7, 2016 at 17:16 Comment(5)
This just gives your home directory (where your shell starts).Awe
It gives path to directory where script you run is.Naphthol
pwd stands for present working directory. This will set the directory to whatever the current directory of the shell is.Kiehl
pwd also works in PowerShell (which is currently considered the default shell on Windows), where it's an alias for Get-Location.Pasto
@Kiehl actually it stands for print working directoryUphemia
T
3

I understand this is outdated, but I couldn't get the former answers to work very satisfactorily, so I wanted to contribute my method in case any one else encounters the same error mentioned in the comments to BumbleBee's answer.

Mine is based on a simple system command. All you feed the function is the name of your script:

extractRootDir <- function(x) {
    abs <- suppressWarnings(system(paste("find ./ -name",x), wait=T, intern=T, ignore.stderr=T))[1];
    path <- paste("~",substr(abs, 3, length(strsplit(abs,"")[[1]])),sep="");
    ret <- gsub(x, "", path);
    return(ret);
}

setwd(extractRootDir("myScript.R"));

The output from the function would look like "/Users/you/Path/To/Script". Hope this helps anyone else who may have gotten stuck.

Tumpline answered 17/3, 2015 at 16:36 Comment(0)
N
2

I was just looking for a solution to this problem, came to this page. I know its dated but the previous solutions where unsatisfying or didn't work for me. Here is my work around if interested.

filename = "your_file.R"
filepath = file.choose()  # browse and select your_file.R in the window
dir = substr(filepath, 1, nchar(filepath)-nchar(filename))
setwd(dir)
Needham answered 24/1, 2016 at 15:59 Comment(1)
Is there a reason why you don't just use setwd( dirname(filepath) ) ?Bollen
E
2

In case you use UTF-8 encoding:

path <- rstudioapi::getActiveDocumentContext()$path
Encoding(path) <- "UTF-8"
setwd(dirname(path))

You need to install the package rstudioapi if you haven't done it yet.

Emotional answered 21/6, 2017 at 8:39 Comment(2)
Error in setwd(dirname(path)) : cannot change working directoryAlfaro
``` Error in setwd(dirname(path)) : cannot change working directory`` your solution not working please check your answerThyrse
F
2

I feel like a mocking bird, but I'm going to say it: I know this post is old, but...

I just recently learned you cannot call the api when running the script from Task Scheduler and a .bat file. I learned this the hard way. Thought those of you who were using any of the rstudioapi:: methods might like to know that. We run lots of script this way overnight. Just recently changed our path to include the api called so we could "dynamically" set the working directory. Then, when the first one we tried with failed when triggered from Task Scheduler, investigation brought that information about.

This is the actual code that brought this issue to light:
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))

Works beautifully if you're running the script though!

Just adding my two cents as I know people still pull these threads up, thought it might be helpful.

Formenti answered 21/2, 2022 at 17:41 Comment(0)
F
0

Most GUIs assume that if you are in a directory and "open", double-click, or otherwise attempt to execute an .R file, that the directory in which it resides will be the working directory unless otherwise specified. The Mac GUI provides a method to change that default behavior which is changeable in the Startup panel of Preferences that you set in a running session and become effective at the next "startup". You should be also looking at:

?Startup

The RStudio documentation says:

"When launched through a file association, RStudio automatically sets the working directory to the directory of the opened file." The default setup is for RStudio to be register as a handler for .R files, although there is also mention of ability to set a default "association" with RStudio for .Rdata and .R extensions. Whether having 'handler' status and 'association' status are the same on Linux, I cannot tell.

http://www.rstudio.com/ide/docs/using/workspaces

Forcible answered 2/12, 2012 at 19:41 Comment(4)
For sure RStudio does not make that assumption.Afterheat
It behaves the way I described it on my machine. I have not done anything special to the RStudio Preferences.Forcible
Does not do that on Linux :)Afterheat
"When launched through a file association" is the key condition here. Some people might be launching Rstudio via a shortcut or a command in the terminal. You need to open the file and have the default for opening .R files be Rstudio. If you open Rstudio first (then open the file) it will not work as described. Through a file association, the above answer works in windows and mac (possibly not linux as @Afterheat points out - but I can't verify this as I don't have a linux machine).Cousins
B
0
dirname(parent.frame(2)$ofile)  

doesn't work for me either, but the following (as suggested in https://mcmap.net/q/101731/-getting-path-of-an-r-script) works for me in ubuntu 14.04

dirname(rstudioapi::getActiveDocumentContext()$path)
Barouche answered 12/4, 2016 at 0:53 Comment(3)
Error: 'getActiveDocumentContext' is not an exported object from 'namespace:rstudioapi' also in Ubuntu 14.04Cardiology
Maybe you can try install rstudioapi package first.Barouche
That's strange. I'm using R-3.2.4 in a 32-bit ubuntu 14.04. I hope it is not because of operating system or different versions of R.Barouche
F
0

Here is another way to do it:

set2 <- function(name=NULL) {
  wd <- rstudioapi::getSourceEditorContext()$path
  if (!is.null(name)) {
    if (substr(name, nchar(name) - 1, nchar(name)) != '.R') 
      name <- paste0(name, '.R')
  }
  else {
    name <- stringr::word(wd, -1, sep='/')
  }
  wd <- gsub(wd, pattern=paste0('/', name), replacement = '')
  no_print <- eval(expr=setwd(wd), envir = .GlobalEnv)
}
set2()
Ferro answered 11/3, 2020 at 10:24 Comment(0)
U
0

Building on @Richie Cotton's, if you use RStudio, here is a snippet that will set the working directory to the current script in every of the cases of script source, run, or knitted:

# Change WD to current file
# - source and knit
srcdir <- getSrcDirectory(function(){})[1]
if (srcdir=="") {
    # - run
    srcdir <- dirname(rstudioapi::getActiveDocumentContext()$path)
}
setwd(srcdir)
rm(srcdir)
Uphemia answered 27/8, 2023 at 17:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.