setwd()
スクリプトで 使用するのは悪い習慣だと言っているのを聞いたことがあります。
- それに関連するリスク/危険性は何ですか?
- より良い代替手段は何ですか?
これは、再現可能なコードの問題です。他のユーザーのコンピューターに存在しないディレクトリを指定すると、そのユーザーはあなたのコードを使用できなくなります。これは、絶対ファイル パスでは特に問題があり、特に Windows ファイル パス (Unix システムで複製することは絶対に不可能です) では問題です。
私の推奨する解決策は、コードの実行を開始する前に、ユーザーが自分のシステムの関連するディレクトリにいる必要があることを指定することです。あなた自身の便宜のためにsetwd(...)
、他の人がそれに気づき、適切にコメントアウトできるコードの先頭に権利を置きたいが、コードの残りの部分はその開始ディレクトリからの相対パスのみを想定している場合、それは私には問題ありません.
Yihui Xie ( の著者knitr
) は、これについて特に強く感じています。
https://groups.google.com/forum/?fromgroups=#!topic/knitr/knM0VWoexT0
ファイルを操作するときはいつでも、それらはソース (Rnw ドキュメントなど) の同じディレクトリの下にあると想定されます。その後、いつでも相対パスを使用でき、setwd() を使用する必要はありません。setwd() を使用すると、再現性の原則に反します。たとえば、setwd('foo/bar/') を使用すると、ディレクトリが他の人のコンピューターに存在しない可能性があります。FAQ 7 を参照してください: https://github.com/yihui/knitr/blob/master/FAQ.md
そして、前述の FAQ 7 から:
[knitr コード チャンク内の作業ディレクトリを変更] は行わない方がよいでしょう。作業ディレクトリは常に getwd() (すべての出力ファイルがここに書き込まれます) ですが、コード チャンクは入力ドキュメントのディレクトリの下で評価されます。R コードの実行中に作業ディレクトリを変更することは、一般的に悪い習慣です。議論については #38 を参照してください。また、再現性が低下するため、可能な限り絶対ディレクトリを避けるようにしてください (代わりに相対ディレクトリを使用してください)。
setwd()
try()でトラップできるエラーが返され、管理できるため、管理しているサーバーで実行されるスクリプトでの使用に関する特定の問題は考えられません。私はsetwd()
パスについて怠惰なときに使用しました-以下を参照してください!
私file.path()
はスクリプトの制作などで広く使用しています。入力ディレクトリ内のファイル間で作業し、出力グラフィックとレポートを別の場所に配置します。したがって、...(テストされていない)の線に沿った何かこれは、を使用するのは少し面倒setwd()
です。
kInDir <- '~/Indir'
kOutDir <- '~/Outdir'
flist <- dir(path=kInDir, pattern='^[a-z]{2,5}\\.csv$')
# note I could have used full.names=T - but it's easier not to...
for (fnam in flist) {
# full path to the report file created
sfnam <- file.path(kOutDir, gsub('.csv', '_report.txt', fnam))
# full path to the csv file that will be created
ofnam <- file.path(kOutDir, gsub('.csv', '_b.csv', fnam))
#
# ok... we're going to process this CSV file...
r1 <- read.csv(file.path(kInDir, fnam))
#
# we''ll put the output from the analysis into this report file
sink(sfnam, split=TRUE)
# processs it... into a new data.frame k1
# blah blah blah...
#
write.csv(k1, file=ofnam, row.names=FALSE)
sink() # turn off this particular report file
}
より良い代替案の質問に向けて:
私は主に個々のプロジェクトで R を使用します (つまり、私は主要なアナリストです)。ただし、他のユーザーと共有する必要があるプロジェクトではこれらを使用します。
RStudioのProjects 機能は、ファイルを整理しておくのに大いに役立ちます。他のユーザーも RStudio を採用すると、単一のファイル ("*.Rproj") を開いて、最後に保存したのと同じ状態でプロジェクトをロードできるという好感を抱くでしょう。
これに加えて、さらに一歩進んだ新しいツールProjectTemplateを見つけました。著者が開発した手法は、あなたがしていることに構造を提供するために使用されます。詳しくはウェブサイトをご覧ください。
Though problems with setwd() have been targeted, I would like to add one more to the what are the alternatives part of the question. We often work with git where the relative path is very convenient
setrelwd <- function(rel_path){
curr_dir <- getwd()
abs_path <- file.path(curr_dir,rel_path)
if(dir.exists(abs_path)){
setwd(abs_path)
}
else
{
warning('Directory does not exist. Please create it first.')
}
}
> setrelwd("Summer2016")
Warning message:
In setrelwd("Summer2016") : Directory does not exist. Please create it first.
Also if you don't want to see the warning message but create a folder right away see Check existence of directory and create if doesn't exist
私が働いている場所で物事をもう少し移植できるようにするために、これをRprofileに入れます
hdrive=
switch(Sys.info()[[1]],
'Linux'="/mnt/hdrive",
'Windows'="H:/",
"Darwin"="/Volumes/hdrive/mnt/hdrive"
)
そのため、共有ドライブにアクセスするための変数を常に持っています。次に、スクリプトで次のように記述できます
setwd(paste(hdrive,"/relative/path/",sep="/"))
そのため、他の人が話している問題のいくつかを回避できます。
私は個人的に次のコードを追加しました。Sys.info() と any() を一意の情報とともに使用します。
最初のステップは、Sys.info() を使用して、コンピューターの一意の識別子を見つけることです。
if(any(Sys.info() == "COMPUTER1")) {
setwd("c:/Users/user1/repos/project/")
}
if(any(Sys.info() == "COMPUTER2")) {
setwd("home/user1/repos/project/")
}
コンピューターの名前をifステートメントに追加し、正しいパスを追加するだけです。マシンごとに新しい if を追加するだけです。
再現のために、その特定のユーザーでない限り、誰の作業ディレクトリも変更しません。