Ответ 1
Используйте source("yourfile.R", chdir = T)
Есть ли способ программно найти путь к R script внутри самого script?
Я спрашиваю об этом, потому что у меня есть несколько сценариев, которые используют RGtk2
и загружают графический интерфейс из файла .glade.
В этих сценариях я обязан поместить инструкцию setwd("path/to/the/script")
в начале, иначе файл .glade(который находится в том же каталоге) не будет найден.
Это нормально, но если я перемещаю script в другой каталог или на другой компьютер, мне нужно изменить путь. Я знаю, это неважно, но было бы неплохо иметь что-то вроде:
setwd(getScriptPath())
Итак, существует ли подобная функция?
Используйте source("yourfile.R", chdir = T)
Это работает для меня:
getSrcDirectory(function(x) {x})
Это определяет анонимную функцию (которая ничего не делает) внутри script, а затем определяет исходный каталог этой функции, который является каталогом, в котором находится script.
Только для RStudio:
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
Это работает при запуске или источнике файла.
Использовать неявный аргумент "-file" для Rscript
Если вы завершаете свой код в пакете, вы всегда можете запрашивать части каталога пакетов.
Вот пример из пакета RGtk2:
> system.file("ui", "demo.ui", package="RGtk2")
[1] "C:/opt/R/library/RGtk2/ui/demo.ui"
>
Вы можете сделать то же самое с каталогом inst/glade/
в ваших источниках, который станет каталогом glade/
в установленном пакете - и system.file()
будет вычислять путь для вас при установке, независимо от ОС.
Этот ответ отлично работает для меня:
script.dir <- dirname(sys.frame(1)$ofile)
Примечание: script должен быть отправлен для возврата правильного пути
Я нашел его в: https://support.rstudio.com/hc/communities/public/questions/200895567-can-user-obtain-the-path-of-current-Project-s-directory-
Но я до сих пор не понимаю, что такое sys.frame(1) $$. Я ничего не нашел об этом в документации R. Кто-нибудь может это объяснить?
#' current script dir
#' @param
#' @return
#' @examples
#' works with source() or in RStudio Run selection
#' @export
z.csd <- function() {
# http://stackoverflow.com/questions/1815606/rscript-determine-path-of-the-executing-script
# must work with source()
if (!is.null(res <- .thisfile_source())) res
else if (!is.null(res <- .thisfile_rscript())) dirname(res)
# http://stackoverflow.com/a/35842176/2292993
# RStudio only, can work without source()
else dirname(rstudioapi::getActiveDocumentContext()$path)
}
# Helper functions
.thisfile_source <- function() {
for (i in -(1:sys.nframe())) {
if (identical(sys.function(i), base::source))
return (normalizePath(sys.frame(i)$ofile))
}
NULL
}
.thisfile_rscript <- function() {
cmdArgs <- commandArgs(trailingOnly = FALSE)
cmdArgsTrailing <- commandArgs(trailingOnly = TRUE)
cmdArgs <- cmdArgs[seq.int(from=1, length.out=length(cmdArgs) - length(cmdArgsTrailing))]
res <- gsub("^(?:--file=(.*)|.*)$", "\\1", cmdArgs)
# If multiple --file arguments are given, R uses the last one
res <- tail(res[res != ""], 1)
if (length(res) > 0)
return (res)
NULL
}
Как насчет использования команд системы и оболочки? С окнами один, я думаю, когда вы открываете script в RStudio, он устанавливает текущий каталог оболочки в каталог script. Возможно, вам придется добавить cd C:\e.g или любой диск, который вы хотите искать (например, shell ('dir C:\\* file_name/s', intern = TRUE) - \\, чтобы избежать escape-символа). Будет работать только для файлов с уникальным именем, если вы не укажете дополнительные подкаталоги (для Linux я начал искать с /). В любом случае, если вы знаете, как найти что-то в оболочке, это обеспечивает макет, чтобы найти его внутри R и вернуть каталог. Если вы работаете или используете script, но я не полностью изучил потенциальные ошибки.
#Get operating system
OS<-Sys.info()
win<-length(grep("Windows",OS))
lin<-length(grep("Linux",OS))
#Find path of data directory
#Linux Bash Commands
if(lin==1){
file_path<-system("find / -name 'file_name'", intern = TRUE)
data_directory<-gsub('/file_name',"",file_path)
}
#Windows Command Prompt Commands
if(win==1){
file_path<-shell('dir file_name /s', intern = TRUE)
file_path<-file_path[4]
file_path<-gsub(" Directory of ","",file_path)
filepath<-gsub("\\\\","/",file_path)
data_directory<-file_path
}
#Change working directory to location of data and sources
setwd(data_directory)
Спасибо за функцию, хотя мне пришлось немного отрегулировать ее следующим образом (W10):
#Windows Command Prompt Commands
if(win==1){
file_path<-shell('dir file_name', intern = TRUE)
file_path<-file_path[4]
file_path<-gsub(" Verzeichnis von ","",file_path)
file_path<-chartr("\\","/",file_path)
data_directory<-file_path
}