Найти местоположение текущего файла.R

Я просмотрел много вопросов, похожих на это (см. Конец поста), но я не нашел никаких решений, которые бы действительно выполняли то, что мне нужно. Я пишу код на Windows или Fedora в зависимости от проекта, и я пишу для людей, которые используют Windows и несколько дистрибутивов Linux.

Часть моей работы - создание R-скриптов для людей, которые автоматически анализируют данные и создают графики. Чаще всего я просто отправляю им скрипт, и он генерирует график. Таким образом, если данные изменяются или расширяются, мне не нужно повторно запускать сценарий для них (также они могут вносить изменения по мере необходимости).

Проблема в том, что я не знаю, как получить R-скрипт, чтобы узнать, где он находится. Было бы очень удобно просто иметь возможность создавать код, который работает следующим образом:

  1. Пользователь сохраняет скрипт в папку, содержащую данные, а затем запускает скрипт.
    • Обычно я просто посылаю сценарий человеку, с которым работаю.
    • Они сохраняют сценарий в папке, содержащей данные, которые они хотят проанализировать / представить.
    • В идеале они просто запускают R, загружают скрипт, затем запускают скрипт.
  2. Скрипт определяет свое собственное местоположение, а затем устанавливает его как рабочий каталог.
  3. Скрипт анализирует данные в своем собственном каталоге.
  4. Скрипт генерирует граф (ы) и сохраняет его в своем собственном каталоге.

Этот вопрос касается только шага 2. Все остальное течет хорошо, пока я могу это сделать. Было бы неплохо иметь что-то вроде:

setwd(FindThisScriptsLocation())

Здесь была предложена строка: source(..., chdir = T), но она не может быть использована скриптом для ссылки на себя, если он не знает свой собственный путь.

Вот несколько связанных вопросов:

4 ответа

Решение

Где -то в процессе "загрузить скрипт" вы передаете имя и путь к скрипту R. Я предлагаю захватить эту информацию и затем использовать скрипт-обертку для выполнения вашего основного скрипта.

Вариант 1 (программно)

функция-обертка, которая принимает в качестве аргумента путь и имя файла скрипта для выполнения

FILE <- "~/Desktop/myFolder/InHere/myScript.R"

Вариант 2 (в интерактивном режиме)

в начале вашей функции оболочки, дайте пользователю кликнуть на файл:

FILE <- file.choose()

ЗАТЕМ:

DIR  <- dirname(FILE)

и там у вас есть каталог / папка, и вы можете выполнить свой скрипт, как обычная передача DIR в качестве параметра

Была такая же проблема, вот что я придумал. Он работает с source() и rmarkdwon::render() в Windows и Linux.

Обновление: функция get_scriptpath() теперь доступна как часть моего пакета envDocument в CRAN. Смотрите 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)
}

Эй, у меня есть возможное решение, которое требует дополнительной начальной работы, но должно быть в состоянии сделать то, что вам нужно.

Сначала заставьте ваш R-скрипт принять параметр, который будет местоположением скрипта. Далее вам просто нужно создать Bash/Batch (по одному для Windows и Unix), который будет

1) получить свой каталог

2) поиск в каталоге R-скрипта (простой поиск *.R)

3) вызовите скрипт R со своим собственным каталогом из шага 1.

Затем вы просто упаковываете сценарии Bash и Batch в папку, которую вы предоставляете своим клиентам, и просите их просто запустить соответствующий сценарий для их среды.

Теоретически, вы должны создавать сценарии Bash / Batch только один раз.

РЕДАКТИРОВАТЬ: я создал простой сценарий bash, который работает для этой проблемы, см. Ниже

#!/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}

Я не очень хорошо разбираюсь в Windows Shell, поэтому вам придется сделать это самостоятельно:P

Вы можете проверить это с помощью этого R-скрипта;

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

Я предполагаю, что это Windows.

Следуя предложению Рикардо: настройте клиентские системы таким образом, чтобы при двойном щелчке скрипта в каталоге скрипта запускался интерпретатор R. Вы также можете назначить специальное расширение для этого поведения (скажем, .Rwd для "R скрипт, устанавливающий рабочий каталог"). Тогда вам не нужно setwd() в сценарии.

Для начала может подойти следующий скрипт командной строки (непроверенный):

pushd %~d1%~p1
R --vanilla < "%1"

ассоциированный .Rwd файлы с этим скриптом.

Если вам нужно source() другие сценарии, рассмотрите возможность использования chdir=T аргумент.

Если вы используете RStudio, просто удерживайте курсор над скриптом, и путь появится

https://stackru.com/images/0830d348e730a9f1a681fb7b321f7aec6096fdac.png

Другие вопросы по тегам