Получить путь к текущему сценарию
Я бы хотел программно установить путь к рабочему каталогу текущего скрипта, но сначала мне нужно получить путь к текущему скрипту.
Поэтому я хотел бы иметь возможность сделать:
current_path = ...retrieve the path of current script ...
setwd(current_path)
Пока что попробовал:
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 возвращает NULL
source("script.R", chdir = TRUE)
Возвращает: Ошибка в файле (имя файла, "r", кодировка = кодировка): невозможно открыть соединение. Дополнительно: Предупреждение: В файле (имя файла, "r", кодировка = кодировка): не удается открыть файл '/script.R': Данный файл или каталог отсутствует
dirname(parent.frame(2)$ofile)
Возвращает: Ошибка в dirname(parent.frame(2)$ofile): ожидается символьный векторный аргумент ..., поскольку parent.frame имеет значение 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)]])
Возвращает: Null, потому что frame_files - это список из 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))
}
}
Возвращает: Ошибка в path.expand (path): неверный аргумент 'path'
Также я видел все ответы здесь, здесь, здесь и здесь. Нет радости
Работать с RStudio 1.1.383
РЕДАКТИРОВАТЬ: Было бы здорово, если бы не было необходимости во внешней библиотеке для достижения этой цели.
3 ответа
В RStudio вы можете получить путь к файлу, отображаемому в данный момент на исходной панели, используя
rstudioapi::getSourceEditorContext()$path
Если вы хотите только каталог, используйте
dirname(rstudioapi::getSourceEditorContext()$path)
Если вы хотите, чтобы имя файла, который был запущен source(filename)
Это немного сложнее. Вам нужно искать переменную srcfile
где-то обратно в стек. Как далеко назад зависит от того, как вы пишете вещи, но это около 4 шагов назад: например,
fi <- tempfile()
writeLines("f()", fi)
f <- function() print(sys.frame(-4)$srcfile)
source(fi)
fi
следует напечатать то же самое на последних двух строках.
Обновление март 2019
На основе ответов Alexis Lucattini и user2554330, чтобы он работал как в командной строке, так и в RStudio. Также решение устаревшего сообщения "as_tibble"
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))
}
Обновление Август 2018
TLDR: пакет here помогает вам создать путь из корневой папки проекта, независимо от того, где в папке hiearchy хранятся сценарии R или документы Rmd.
Здесь пакет остается доступным на CRAN. Версия для разработки была перемещена на https://github.com/r-lib/here. Пункты, упомянутые на сайтах, указанных ниже, остаются в силе.
Предыдущий ответ
Прочтите Оду здесь:
Есть ли у вас: setwd() в ваших скриптах? Пожалуйста, прекратите делать это. Это делает ваш сценарий очень хрупким, запрограммированным точно в одно время и в одном месте. Как только вы переименуете или переместите каталоги, он сломается. Или, может быть, вы получите новый компьютер? Или может кому-то еще нужно запустить ваш код?
[...]
Классическое представление проблемы: неловкость вокруг путей построения и / или установки рабочего каталога в проектах с подкаталогами. Особенно, если вы используете R Markdown и knitr, которые запутывают многих людей с помощью поведения по умолчанию "рабочий каталог = каталог, в котором находится этот файл". [...]
Установите здесь пакет:
install.packages("here")
library(here)
here()
here("construct","a","path")
Документация here()
функция:
Начиная с текущего рабочего каталога во время загрузки пакета, здесь будет проходить иерархия каталогов вверх, пока не будет найден каталог, удовлетворяющий хотя бы одному из следующих условий:
- содержит файл, соответствующий [.]Rproj$ с содержанием, совпадающим с ^ Версия: в первой строке
- [... другие опции...]
- содержит каталог.git
После установки корневой каталог не изменяется во время активного сеанса R. здесь () затем добавляет аргументы в корневой каталог.
Разрабатываемая версия пакета доступна на github.
Если вы запускаете Rscript через командную строку и т. Д.
Rscript /path/to/script.R
Функция ниже назначит this_file
в /path/to/script
library(tidyverse)
get_this_file <- function(){
commandArgs() %>%
tibble::as.tibble() %>%
tidyr::separate(col=value, into=c("key", "value"), sep="=", fill='right') %>%
dplyr::filter(key == "--file") %>%
dplyr::pull(value)
}
this_file <- get_this_file()
Вот настраиваемая функция для получения пути к файлу в R, RStudio или из 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
Другой вариант получить текущий путь к скрипту funr::get_script_path()
и вам не нужно запускать свой скрипт с помощью RStudio.
Следующее решает проблему для трех случаев: кнопка источника RStudio, консоль RStudio R (source(...)
, если файл все еще находится на панели "Источник") или в консоли ОС через 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)
У меня были проблемы со всем этим, потому что они полагаются на библиотеки, которые я не мог использовать (из-за packrat) до тех пор, пока не установил рабочий каталог (вот почему мне нужно было получить путь для начала).
Итак, вот подход, который просто использует базовый R. (EDITED для обработки символов windows \ в дополнение к путям / in)
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])
)
Следующий код указывает каталог запущенного Rscript, если вы запускаете его из Rstudio или из командной строки с помощью команды Rscript:
if (rstudioapi::isAvailable()) {
if (require('rstudioapi') != TRUE) {
install.packages('rstudioapi')
}else{
library(rstudioapi) # load it
}
wdir <- dirname(getActiveDocumentContext()$path)
}else{
wdir <- getwd()
}
setwd(wdir)
Если вы не хотите использовать (или должны помнить) код, просто наведите указатель мыши на сценарий, и появится путь
ht tps:https://stackru.com/images/e8e1204e4b59d1eaac2302bb49c47b89fc2a9d85.png