179

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.

gagarine
  • 4,190
  • 2
  • 30
  • 39
Stat-R
  • 5,040
  • 8
  • 42
  • 68

18 Answers18

135

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.

Richie Cotton
  • 118,240
  • 47
  • 247
  • 360
  • your own answer at http://stackoverflow.com/a/35842176/1247080 works (one must include the dirname though). I added it – Stat-R Apr 15 '16 at 19:15
  • Doesn't work for me. I get `Error: 'getActiveDocumentContext' is not an exported object from 'namespace:rstudioapi'` – Andru Nov 22 '16 at 20:32
  • @Andru 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. – Richie Cotton Nov 29 '16 at 19:23
  • 8
    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 @Andru 's comment – Megatron Oct 03 '17 at 17:30
  • I run `setwd(dirname(rstudioapi::getActiveDocumentContext()$path))` on a Mac and I got Error: 'getActiveDocumentContext' is not an exported object from 'namespace:rstudioapi' – Giacomo Oct 29 '17 at 12:33
  • 1
    @giac_man It sounds like you are using a very old version of the `rstudioapi` package. Try updating to the latest one. – Richie Cotton Nov 01 '17 at 02:15
  • 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. – Sandu Ursu Sep 14 '19 at 17:36
  • @SanduUrsu Correct: the console is not an active document, so `rstudioapi::getActiveDocumentContext()$path` is `""`. – Richie Cotton Sep 16 '19 at 17:49
  • 2
    `setwd(getSrcDirectory()[1])` didn't work for me when I sourced the file. The `rstudioapi` solution worked. – filups21 Nov 01 '19 at 21:56
  • @RichieCotton is there a way to automatically jump to that working directory and showing it content in 'Files' tab in RStudio? – mjs Feb 10 '20 at 10:52
  • 1
    @mjs 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. – Richie Cotton Feb 20 '20 at 15:40
  • @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. – mjs Feb 21 '20 at 09:00
  • getSrcDirectory() does not work as it needs an object or function as input. – Simon Chemnitz-Thomsen Sep 26 '22 at 10:29
  • 1
    @filups21 @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)` – mastropi Dec 15 '22 at 19:01
  • @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. – mastropi Dec 15 '22 at 19:03
68

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

BumbleBee
  • 986
  • 9
  • 19
  • 112
    didn't work for me either: `Error in dirname(parent.frame(2)$ofile) : a character vector argument expected` – tumultous_rooster Mar 16 '15 at 17:51
  • 1
    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 ... – BumbleBee Mar 17 '15 at 14:42
  • 4
    Same problem here as @Matt O'Brien on Linux. – patapouf_ai Jun 11 '15 at 11:41
  • running on windows, same proble here as @bisounours_tronconneuse – HappyCoding Oct 10 '15 at 14:57
  • 5
    Working perfectly if sourced. – m-dz Jul 20 '16 at 13:24
  • 2
    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. – Contango Jun 17 '17 at 16:55
  • 1
    @BumbleBee 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. – tavalendo Jun 01 '18 at 12:57
  • 2
    This works for me on a Mac when sourcing a file. However, as @Contango 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. – bmosov01 Jun 05 '18 at 18:08
  • @MrSCoder Do you have any error message or alike? Maybe the solution is already outdated. Did you try another solution here? – BumbleBee Feb 04 '20 at 22:17
13

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.

gagarine
  • 4,190
  • 2
  • 30
  • 39
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.

Juan Pueyo
  • 154
  • 1
  • 3
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.

Katie Renwick
  • 93
  • 1
  • 5
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.

sietemonos
  • 101
  • 1
  • 2
6

If you work on Linux you can try this:

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

It works for me.

Taz
  • 5,755
  • 6
  • 26
  • 63
  • 1
    This just gives your home directory (where your shell starts). – Caner Aug 17 '16 at 23:39
  • It gives path to directory where script you run is. – Taz Aug 18 '16 at 08:30
  • 2
    pwd stands for present working directory. This will set the directory to whatever the current directory of the shell is. – PeterVermont Apr 13 '17 at 17:27
  • `pwd` also works in PowerShell (which is currently considered the default shell on Windows), where it's an alias for `Get-Location`. – BroVic Apr 17 '20 at 23:09
  • @PeterVermont actually it stands for [print working directory](https://www.gnu.org/software/coreutils/manual/html_node/pwd-invocation.html#pwd-invocation) – robertspierre Aug 27 '23 at 17:56
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])
namu.net
  • 59
  • 1
  • 1
  • 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. – tavalendo Jun 01 '18 at 13:09
5

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.

Will
  • 4,241
  • 4
  • 39
  • 48
  • 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. – BroVic Apr 17 '20 at 23:11
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.

TayTay
  • 6,882
  • 4
  • 44
  • 65
3
setwd(this.path::here())

works both for sourced and "active" scripts.

giacomo
  • 39
  • 3
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)
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.

jormaga
  • 301
  • 1
  • 2
  • 13
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.

yewing
  • 21
  • 1
  • 2
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

IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • 4
    For sure RStudio does not make that assumption. – nico Dec 02 '12 at 19:45
  • 1
    It behaves the way I described it on my machine. I have not done anything special to the RStudio Preferences. – IRTFM Dec 02 '12 at 19:51
  • 2
    Does not do that on Linux :) – nico Dec 03 '12 at 07:16
  • 3
    "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 @nico points out - but I can't verify this as I don't have a linux machine). – WetlabStudent Dec 29 '14 at 17:57
0
dirname(parent.frame(2)$ofile)  

doesn't work for me either, but the following (as suggested in https://stackoverflow.com/a/35842176/992088) works for me in ubuntu 14.04

dirname(rstudioapi::getActiveDocumentContext()$path)
Community
  • 1
  • 1
Lamothy
  • 337
  • 4
  • 17
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()
m02ph3u5
  • 3,022
  • 7
  • 38
  • 51
Issam
  • 1
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)
robertspierre
  • 3,218
  • 2
  • 31
  • 46