Подтвердить что ты не робот

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?

4b9b3361

Ответ 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)
}