Получить путь от текущего script
Я хотел бы установить рабочий каталог на путь текущего script программно, но сначала мне нужно получить путь к текущему script.
Итак, я хотел бы иметь возможность сделать:
current_path = ...retrieve the path of current script ...
setwd(current_path)
Так же, как в меню RStudio:
![RStudio установить рабочий каталог]()
До сих пор я пытался:
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", encoding = encoding): невозможно открыть файл '/ 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)]])
Возвращает: Нуль, потому что 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))
}
}
Возвращает: ошибка в пути .expand(путь): недопустимый аргумент "путь"
Также я увидел все ответы здесь, здесь, здесь и здесь.
Нет радости.
Работа с RStudio 1.1.383
EDIT: Было бы здорово, если бы не понадобилась внешняя библиотека для этого.
Ответы
Ответ 1
В 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
должен печатать то же самое на двух последних строках.
Ответ 2
Обновление августа 2018
TL;DR: пакет here помогает вам создать путь из корневой папки проекта, независимо от того, где в папке hiearchy хранятся скрипты R или документы Rmd.
Здесь пакет остается доступным на CRAN. Версия для разработки была перемещена на github.com/r-lib/here. Пункты, упомянутые на сайтах, указанных ниже, остаются в силе.
Предыдущий ответ
Прочтите Оду здесь:
Есть ли у вас setwd() в ваших скриптах? Пожалуйста, прекратите делать это. Это делает ваш сценарий очень хрупким, запрограммированным точно в одно время и в одном месте. Как только вы переименовываете или перемещаете каталоги, он ломается. Или, может быть, вы получите новый компьютер? Или, может быть, кому-то еще нужно запустить ваш код?
[...]
Классическое представление проблемы: неловкость вокруг путей построения и/или установки рабочего каталога в проектах с подкаталогами. Особенно, если вы используете R Markdown и knitr, которые запутывают многих людей с помощью поведения по умолчанию "рабочий каталог = каталог, в котором находится этот файл". [...]
Установите здесь пакет:
install.packages("here")
library(here)
here()
here("construct","a","path")
Документирование функции here()
:
Начиная с текущего рабочего каталога во время загрузки пакета, здесь будет проходить иерархия каталогов вверх, пока не будет найден каталог, удовлетворяющий хотя бы одному из следующих условий:
- содержит файл, соответствующий [.] Rproj $ с содержанием, совпадающим с ^ Версия: в первой строке
- [... другие опции...]
- содержит каталог .git
После установки корневой каталог не изменяется во время активного сеанса R. здесь() затем добавляет аргументы в корневой каталог.
Разрабатываемая версия пакета доступна на github.
Ответ 3
Если вы запускаете Rscript через командную строку и т.д.
Rscript /path/to/script.R
Функция ниже назначит this_file
/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()
Ответ 4
Обновление март 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))
}
Ответ 5
Другой способ получить текущий путь к скрипту - это funr::get_script_path()
и вам не нужно запускать ваш скрипт с помощью RStudio.
Ответ 6
У меня были проблемы со всем этим, потому что они полагаются на библиотеки, которые я не мог использовать (из-за packrat) до тех пор, пока не установил рабочий каталог (именно поэтому мне нужно было получить путь для начала).
Итак, вот подход, который просто использует базу R. (EDITED для обработки окон\символов в дополнение к/в путях)
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])
)