相対パスを使用してファイルを取得する方法は、大規模なコードベースを扱うときに便利です。他のプログラミング言語では、ソース先のファイルのディレクトリに対する相対パスを使用してファイルを取得するメカニズムが明確に定義されています。例としては、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
その後議論GitHub の @hadley と相談して、私の質問が R の一般的な開発パターンに反していることに気付きました。
getwd()
R では、ソースとなるファイルは、作業ディレクトリ ( ) がファイルが存在するディレクトリに設定されていると想定していることが多いようです。これを機能させるために、 には、デフォルト値が である引数が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)
}