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

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

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

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

  • Пользователь сохраняет script в папку, содержащую данные, затем запускает script.
    • Обычно я просто отправляю сообщение script лицу, с которым я работаю.
    • Они сохраняют script в папку, содержащую данные, которые они хотят проанализировать/графически.
    • В идеале они просто запустили R, загрузили script, а затем запустили script.
  • Script определяет свое собственное местоположение, а затем устанавливает это как рабочий каталог.
  • Script анализирует данные внутри своего собственного каталога.
  • Script создает график и сохраняет его в свой собственный каталог.

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

setwd(FindThisScriptsLocation())

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

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

Ответы

Ответ 1

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

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

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

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

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

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

FILE <- file.choose()

THEN

DIR  <- dirname(FILE)

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

Ответ 2

Если бы та же проблема, вот что я придумал. Он работает с source() и rmarkdwon:: render() на окнах и на 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)
}

Ответ 3

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

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

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

2) найдите каталог для R script (простой поиск *.R)

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

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

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

EDIT: я создал простой Bash script, который работает для этой проблемы, см. ниже

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

Ответ 4

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

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

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

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

Свяжите .Rwd файлы с этим script.

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