Find location of current .R file
Had the same problem, here's what I came up with. It works with source() and rmarkdwon::render() on windows and on linux.
Update: the function get_scriptpath() is now available as part of my envDocument package on CRAN. See https://cran.r-project.org/package=envDocument
#' Get the path of the calling script
#'
#' \code{get_scriptpath} returns the full path of the script that called this function (if any)
#' or NULL if path is not available
#'
#' @examples
#' mypath <- get_scriptpath()
#' @export
#'
get_scriptpath <- function() {
# location of script can depend on how it was invoked:
# source() and knit() put it in sys.calls()
path <- NULL
if(!is.null(sys.calls())) {
# get name of script - hope this is consisitent!
path <- as.character(sys.call(1))[2]
# make sure we got a file that ends in .R, .Rmd or .Rnw
if (grepl("..+\\.[R|Rmd|Rnw]", path, perl=TRUE, ignore.case = TRUE) ) {
return(path)
} else {
message("Obtained value for path does not end with .R, .Rmd or .Rnw: ", path)
}
} else{
# Rscript and R -f put it in commandArgs
args <- commandArgs(trailingOnly = FALSE)
}
return(path)
}
somewhere in the "load the script" process, you are passing the name and path of the R script. I'm suggesting to capture that information and then use a wrapper script to execute your main script.
Option 1 (programatically)
the wrapper function that takes as an argument the path and fiile name of the script to execute
FILE <- "~/Desktop/myFolder/InHere/myScript.R"
Option 2 (interactively)
at the start of your wrapper function, let the user click through to the file:
FILE <- file.choose()
THEN:
DIR <- dirname(FILE)
and there you have your directory/folder and you can execute your script as normal passing DIR
as a parameter
I assume this is Windows.
Following up Ricardo's suggestion: Have the client's systems set up in a way that, if a script is double-clicked, the R interpreter is started in the directory of the script. You could also assign a special extension for this behavior (say, .Rwd
for "R script setting the work directory"). Then, you don't need to setwd()
within the script.
For starters, the following command line script might do (untested):
pushd %~d1%~p1
R --vanilla < "%1"
Associate .Rwd
files with this script.
If you need to source()
other scripts, consider using the chdir=T
argument.
Hey I have a possible solution that's a little bit of extra initial work, but should be able to do what you need.
First make your R script take in a parameter which will be the location of the script. Next you just need to create a Bash/Batch (one each for windows and unix) that will
1) get its own directory
2) search the directory for an R script (simple *.R search)
3) call the R script with it's own directory from step 1.
Then you simply package the Bash and Batch scripts with the folder you give to your clients and ask them to just run the relevant script for their environment.
You should, in theory, only have to create the Bash/Batch scripts once.
EDIT: I've created a simple bash script that works for this problem, see below
#!/bin/bash
#Modify the search string to narrow the search
SEARCH_STRING="*.R"
#Get the current directory
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo ${DIR}
#Get the name of the R script
R_SCRIPT=`find $DIR -name ${SEARCH_STRING} -type f -exec basename {} \;`
echo ${R_SCRIPT}
Rscript ${R_SCRIPT} ${DIR}
I'm not so well versed in the Windows Shell so you'll have to do that one yourself :P
You can test it with this R script;
options(echo = FALSE) #So we don't get the script echo'd
arguments <- commandArgs(trailingOnly = TRUE) #getting the arguments
working_directory <- arguments[1]
setwd(working_directory)
getwd() #print out to test