R: поиск файлов с использованием относительного пути
Поиск файлов с использованием относительного пути полезен при работе с большими кодовыми базами. Другие языки программирования имеют четко определенные механизмы для поиска файлов с использованием пути относительно каталога файла, в который поступает источник. Например, Ruby require_relative
. Что является хорошим способом реализации относительного источника поиска в R?
Ниже приводится то, что я собрал вместе, используя разные рецепты и сообщения в форумах R. Это работало хорошо для меня для прямой разработки, но не является надежным. Например, он ломается, когда файлы загружаются через библиотеку testthat
, в частности auto_test()
. rscript_stack()
возвращает character(0)
.
# Returns the stack of RScript files
rscript_stack <- function() {
Filter(Negate(is.null), lapply(sys.frames(), function(x) x$ofile))
}
# Returns the current RScript file path
rscript_current <- function() {
stack <- rscript_stack()
r <- as.character(stack[length(stack)])
first_char <- substring(r, 1, 1)
if (first_char != '~' && first_char != .Platform$file.sep) {
r <- file.path(getwd(), r)
}
r
}
# Sources relative to the current script
source_relative <- function(relative_path, ...) {
source(file.path(dirname(rscript_current()), relative_path), ...)
}
Знаете ли вы о лучшей реализации source_relative
?
Ответы
Ответ 1
После обсуждение с @hadley на GitHub я понял, что мой вопрос идет вразрез с общими шаблонами развития в R.
Похоже, что в R файлах, которые являются источниками, часто предполагается, что рабочий каталог (getwd()
) установлен в каталог, в котором они находятся. Для выполнения этой работы source
имеет аргумент chdir
, значение по умолчанию которого FALSE
. Когда установлено значение TRUE
, он изменит рабочий каталог на каталог файла, который будет отправлен.
Вкратце:
-
Предположим, что source
всегда относительный, потому что рабочий каталог файла, в котором находится источник, установлен в каталог, в котором находится файл.
-
Чтобы сделать эту работу, всегда устанавливайте chdir=T
при отправке файлов из другого каталога, например, source('lib/stats/big_stats.R', chdir=T)
.
Для удобного поиска целых каталогов предсказуемым образом я написал sourceDir
, который отправляет файлы в каталог в алфавитном порядке.
sourceDir <- function (path, pattern = "\\.[rR]$", env = NULL, chdir = TRUE)
{
files <- sort(dir(path, pattern, full.names = TRUE))
lapply(files, source, chdir = chdir)
}