Get the path of current script

RRstudio

R Problem Overview


I would like to set the working directory to the path of current script programmatically but first I need to get the path of current script.

So I would like to be able to do:

current_path = ...retrieve the path of current script ...
setwd(current_path) 

Just like the RStudio menu does: RStudio set working directory

So far I tried:

initial.options <- commandArgs(trailingOnly = FALSE)
file.arg.name <- "--file="
script.name <- sub(file.arg.name, "", initial.options[grep(file.arg.name, initial.options)])
script.basename <- dirname(script.name)

> script.name returns NULL

source("script.R", chdir = TRUE)

> Returns: > Error in file(filename, "r", encoding = encoding) : cannot open the > connection In addition: Warning message: In file(filename, "r", > encoding = encoding) : cannot open file '/script.R': No such file or > directory

dirname(parent.frame(2)$ofile)

> Returns: Error in dirname(parent.frame(2)$ofile) : a character vector argument expected > ...because parent.frame is null

frame_files <- lapply(sys.frames(), function(x) x$ofile)
frame_files <- Filter(Negate(is.null), frame_files)
PATH <- dirname(frame_files[[length(frame_files)]])

> Returns: Null because frame_files is a list of 0

thisFile <- function() {
    cmdArgs <- commandArgs(trailingOnly = FALSE)
    needle <- "--file="
    match <- grep(needle, cmdArgs)
    if (length(match) > 0) {
        # Rscript
        return(normalizePath(sub(needle, "", cmdArgs[match])))
    } else {
        # 'source'd via R console
        return(normalizePath(sys.frames()[[1]]$ofile))
    }
}

> Returns: Error in path.expand(path) : invalid 'path' argument

Also I saw all answers from here, here, here and here. No joy.

Working with RStudio 1.1.383

> EDIT: It would be great if there was no need for an external library to achieve this.

R Solutions


Solution 1 - R

In RStudio, you can get the path to the file currently shown in the source pane using

rstudioapi::getSourceEditorContext()$path

If you only want the directory, use

dirname(rstudioapi::getSourceEditorContext()$path)

If you want the name of the file that's been run by source(filename), that's a little harder. You need to look for the variable srcfile somewhere back in the stack. How far back depends on how you write things, but it's around 4 steps back: for example,

fi <- tempfile()
writeLines("f()", fi)
f <- function() print(sys.frame(-4)$srcfile)
source(fi)
fi

should print the same thing on the last two lines.

Solution 2 - R

Update March 2019

Based on Alexis Lucattini and user2554330 answers, to make it work on both command line and RStudio. Also solving the "as_tibble" deprecated message

library(tidyverse)
getCurrentFileLocation <-  function()
{
    this_file <- commandArgs() %>% 
    tibble::enframe(name = NULL) %>%
    tidyr::separate(col=value, into=c("key", "value"), sep="=", fill='right') %>%
    dplyr::filter(key == "--file") %>%
    dplyr::pull(value)
    if (length(this_file)==0)
    {
      this_file <- rstudioapi::getSourceEditorContext()$path
    }
    return(dirname(this_file))
}

Solution 3 - R

Update August 2018

TLDR: The here package helps you build a path from the project's root folder no matter where in the folder hiearchy the R scripts or Rmd documents are stored.

The here package remains available on CRAN. The development version has been moved to github.com/r-lib/here. The points mentioned in the sites quoted below remain valid.

Previous answer

Read the Ode to the here package:

> Do you: > Have setwd() in your scripts? PLEASE STOP DOING THAT. This makes your script very fragile, hard-wired to exactly one time and place. As soon as you rename or move directories, it breaks. Or maybe you get a new computer? Or maybe someone else needs to run your code?

> [...]

> Classic problem presentation: Awkwardness around building paths and/or setting working directory in projects with subdirectories. Especially if you use R Markdown and knitr, which trips up alot of people with its default behavior of “working directory = directory where this file lives”. [...]

Install the here package:

install.packages("here")
library(here)
here()
here("construct","a","path")

Documentation of the here() function:

> Starting with the current working directory during package load time, > here will walk the directory hierarchy upwards until it finds > a directory that satisfies at least one of the following conditions: > > * contains a file matching [.]Rproj$ with contents matching ^Version: in > the first line > * [... other options ...] > * contains a directory .git > > Once established, the root directory doesn't change during the active > R session. here() then appends the arguments to the root directory.

The development version of the here package is available on github.

Solution 4 - R

If you're running an Rscript through the command-line etc

Rscript /path/to/script.R

The function below will assign this_file to /path/to/script

library(tidyverse)
get_this_file <- function(){
    commandArgs() %>% 
       tibble::enframe(name=NULL) %>%
       tidyr::separate(col=value, into=c("key", "value"), sep="=", fill='right') %>%
       dplyr::filter(key == "--file") %>%
       dplyr::pull(value)
}
this_file <- get_this_file()

Solution 5 - R

Here is a custom function to obtain the path of a file in R, RStudio, or from an Rscript:

stub <- function() {}
thisPath <- function() {
  cmdArgs <- commandArgs(trailingOnly = FALSE)
  if (length(grep("^-f$", cmdArgs)) > 0) {
    # R console option
    normalizePath(dirname(cmdArgs[grep("^-f", cmdArgs) + 1]))[1]
  } else if (length(grep("^--file=", cmdArgs)) > 0) {
    # Rscript/R console option
    scriptPath <- normalizePath(dirname(sub("^--file=", "", cmdArgs[grep("^--file=", cmdArgs)])))[1]
  } else if (Sys.getenv("RSTUDIO") == "1") {
    # RStudio
    dirname(rstudioapi::getSourceEditorContext()$path)
  } else if (is.null(attr(stub, "srcref")) == FALSE) {
    # 'source'd via R console
    dirname(normalizePath(attr(attr(stub, "srcref"), "srcfile")$filename))
  } else {
    stop("Cannot find file path")
  }
}

https://gist.github.com/jasonsychau/ff6bc78a33bf3fd1c6bd4fa78bbf42e7

Solution 6 - R

Another option to get current script path is funr::get_script_path() and you don't need run your script using RStudio.

Solution 7 - R

I had trouble with all of these because they rely on libraries that I couldn't use (because of packrat) until after setting the working directory (which was why I needed to get the path to begin with).

So, here's an approach that just uses base R. (EDITED to handle windows \ characters in addition to / in paths)

args = commandArgs()

scriptName = args[substr(args,1,7) == '--file=']

if (length(scriptName) == 0) {
  scriptName <- rstudioapi::getSourceEditorContext()$path
} else {
  scriptName <- substr(scriptName, 8, nchar(scriptName))
}

pathName = substr(
  scriptName, 
  1, 
  nchar(scriptName) - nchar(strsplit(scriptName, '.*[/|\\]')[[1]][2])
)

Solution 8 - R

The following solves the problem for three cases: RStudio source Button, RStudio R console (source(...), if the file is still in the Source pane) or the OS console via Rscript:

this_file = gsub("--file=", "", commandArgs()[grepl("--file", commandArgs())])
if (length(this_file) > 0){
  wd <- paste(head(strsplit(this_file, '[/|\\]')[[1]], -1), collapse = .Platform$file.sep)
}else{
  wd <- dirname(rstudioapi::getSourceEditorContext()$path)
}

print(wd)

Solution 9 - R

The following code gives the directory of the running Rscript if you are running it either from Rstudio or from the command line using Rscript command:

if (rstudioapi::isAvailable()) {
  if (require('rstudioapi') != TRUE) {
    install.packages('rstudioapi')
  }else{
    library(rstudioapi) # load it
  }
 wdir <- dirname(getActiveDocumentContext()$path)
}else{
 wdir <- getwd()
}

setwd(wdir)

Solution 10 - R

If you don't want to use (or have to remember) code, simply hover over the script and the path will appear

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPanos Kal.View Question on Stackoverflow
Solution 1 - Ruser2554330View Answer on Stackoverflow
Solution 2 - RJuan BernabeView Answer on Stackoverflow
Solution 3 - RPaul RougieuxView Answer on Stackoverflow
Solution 4 - RAlexis LucattiniView Answer on Stackoverflow
Solution 5 - RJason ChauView Answer on Stackoverflow
Solution 6 - RManuel Sánchez MendozaView Answer on Stackoverflow
Solution 7 - RDov RosenbergView Answer on Stackoverflow
Solution 8 - RshosacoView Answer on Stackoverflow
Solution 9 - RMohamed Ismaiel AhmedView Answer on Stackoverflow
Solution 10 - RstevecView Answer on Stackoverflow