web-dev-qa-db-ja.com

現在のスクリプトのパスを取得する

作業ディレクトリをプログラムで現在のスクリプトのパスに設定したいのですが、最初に現在のスクリプトのパスを取得する必要があります。

だから私はできるようにしたい:

current_path = ...retrieve the path of current script ...
setwd(current_path) 

RStudioメニューのように: RStudio set working directory

これまで私は試しました:

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)

Returns:file(filename、 "r"、encoding = encoding)のエラー:接続を開くことができませんさらに:警告メッセージ:In file(filename、 「r」、エンコーディング=エンコーディング):ファイル '/script.R'を開けません:そのようなファイルまたはディレクトリはありません

dirname(parent.frame(2)$ofile)

Returns: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)]])

Returns:frame_filesは0のリストであるためNull

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))
    }
}

Returns:path.expand(path)のエラー:無効な 'path'引数

また、 hereherehere および here からのすべての回答を見ました。喜びはありません。

RStudio 1.1.383の操作

EDIT:これを達成するために外部ライブラリが必要ないのであれば素晴らしいことです。

23
Panos Kal.

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行に同じものを印刷する必要があります。

45
user2554330

2018年8月更新

TLDRhere パッケージは、プロジェクトのルートフォルダーからパスを構築するのに役立ちます。 RスクリプトまたはRmdドキュメントが保存されます。

here パッケージはCRANで引き続き利用可能です。開発バージョンは github.com/r-lib/here に移動しました。以下に引用されているサイトで言及されているポイントは有効なままです。

前の答え

hereパッケージへの賛辞 を読んでください:

あなた:あなたのスクリプトにsetwd()がありますか?それをやめてください。これにより、スクリプトは非常に脆弱になり、一度だけ、特定の場所に固定されます。ディレクトリの名前を変更または移動すると、すぐに壊れます。それとも、新しいコンピューターを入手しますか?それとも、誰かがあなたのコードを実行する必要があるのでしょうか?

[...]

古典的な問題の提示:サブディレクトリを含むプロジェクトでパスを構築したり、作業ディレクトリを設定したりすることに関する厄介さ。特に、R Markdownとknitrを使用する場合は、「作業ディレクトリ=このファイルが存在するディレクトリ」というデフォルトの動作で多くの人をつまずかせます。 [...]

here パッケージをインストールします。

install.packages("here")
library(here)
here()
here("construct","a","path")

here()関数のドキュメント:

パッケージのロード時に現在の作業ディレクトリから開始し、次の条件の少なくとも1つを満たすディレクトリが見つかるまでディレクトリ階層を上に向かって歩きます。

  • 最初の行に[。] Rproj $に一致するファイルと、^ Version:に一致するコンテンツが含まれています
  • [... 別のオプション ...]
  • ディレクトリ.gitが含まれています

確立されると、アクティブなRセッション中にルートディレクトリは変更されません。 here()は、ルートディレクトリに引数を追加します。

ここでパッケージはgithubで入手可能 の開発バージョン。

10
Paul Rougieux

コマンドラインなどで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()
3

現在のスクリプトパスを取得する別のオプションはfunr::get_script_path()です。RStudioを使用してスクリプトを実行する必要はありません。

2019年3月更新

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))
}
2
Juan Bernabe

これらはすべて、作業ディレクトリを設定するまで(Packratのせいで)使用できないライブラリに依存しているため、これらすべてに問題がありました(そのため、最初にパスを取得する必要がありました)。

したがって、ベースRのみを使用するアプローチを次に示します(パス内の/に加えて、ウィンドウ\文字を処理するために編集)

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])
)

1
Dov Rosenberg