ケィオスの時系列解析メモランダム

時系列解析、生体情報解析などをやわらかく語ります

【Rでコピペでパス指定】Windows環境でエスケープ文字"\"をエスケープ:裏技、raw stringリテラル

Windowsのファイルパスではディレクトリ区切りに、バックスラッシュ「\」、あるいは、日本語環境では円マーク「¥」が使われます。一方、Rの文字列ではバックスラッシュ「\」はエスケープ文字として扱われるため、文字として「\」を表示したい場合は、「\」を2回書いて「\\」としなければなりません。

 このルールは、Windowsでファイルパスを指定するときに面倒な問題を引き起こします。

 たとえば、

フォルダへのパスが

"D:\Document\AAA\BBB\CCC\DDD\EEE\FFF\GGG\HHH"

のとき、「\」をすべて「\\」に書き換えて、

"D:\\Document\\AAA\\BBB\\CCC\\DDD\\EEE\\FFF\\GGG\\HHH"

とするか、「\」をすべて「/」に書き換えて、

"D:/Document/AAA/BBB/CCC/DDD/EEE/FFF/GGG/HHH"

とする必要があります。

 もちろん、Rの文字置換の機能を使えば、一気に置換できるのですが、その操作すら私には面倒です。私としては、フォルダへのパスを、アドレスバーからコピペして終わりにしたいです。

 ということで、今回はその方法を説明します。読むのが面倒な方のために、先に答えを言っておくと、"..." の代わりに、

r"(D:\Document\AAA\BBB\CCC\DDD\EEE\FFF\GGG\HHH)"

のように、r"(...)"を使えば良いのです。 ... の部分にファイルパスをコピー&ペーストすれば、区切り文字を修正する必要はなくなります。

アドレスバーのパスをr"(...)"で囲むとエスケープ文字がエスケープできる

裏技 raw string リテラル r"(...)"

 Rのバージョン4.0から、"raw string リテラル"の表現方法 r"(...)" が加わったようです。リテラル (literal)は、「文字どおり」、「そのまま」みたいな意味です。

 ダブルクォーテーションで囲む "・・・" のような表記をプログラミングで使ったことがあるかもしれません。Rでも、文字列を入力通りにそのまま代入するときは、

x <- "Hoge!"

のようにします。

 ただ、この表記の問題は、エスケープ文字 (バックスラッシュ)が、そのまま表示できないことです。

 たとえば、

x <- "AAA\BBB"

は、「'\B' は文字列で認識されないエスケープです」というエラーになります。

 この問題を解決するのが、今回紹介するraw string リテラル r"(...)"です。日本語に訳せば、生文字列そのまんまです。 生文字列そのまんまでは、"..." の代わりに r"(...)" とします。

 つまり、x <- "AAA\BBB"ではなく、

x <- r"(AAA\BBB)"

とすれば、「エスケープ」が何とかというエラーはでません。

Rでそのままコピペでパス指定

 ということで、「Windows環境でのフォルダへのパスを、アドレスバーからコピペして終わりにしたい」という私の夢は、raw string リテラルを使えばかなえられます。

 具体例を示しておきます。フォルダへのパスが

"D:\Document\AAA\BBB\CCC\DDD\EEE\FFF\GGG\HHH"

のときは、Rスクリプトを以下のようすれば、この文字列のコピペでパスを指定できます。

original_Win_path <- r"(D:\Document\AAA\BBB\CCC\DDD\EEE\FFF\GGG\HHH)"
setwd(original_Win_path)

あるいは、バックスラッシュ「\」を、「/」に置き換えたいときは、

original_Win_path <- r"(D:\Document\AAA\BBB\CCC\DDD\EEE\FFF\GGG\HHH)"
dir <- gsub(r"(\)", "/", original_Win_path, fixed = TRUE)
setwd(dir)

とします。

 raw stringリテラルは、 r"(...)"だけでなく、r"{...}"も、r"[...]"も、同じ働きをします。なぜ複数の表現があるのかは、raw stringリテラル自体をそのまま表現できないからです。

 たとえば、「raw stringリテラルは r"(Hoge\Hoge\Hoge)"のように表記します」と表示したいとき、

ex_string <- r"(raw stringリテラルは r"(Hoge\Hoge\Hoge)"のように表記します)"

とすれば、エラーになりうまくいきません.そんなときは、raw stringリテラルの別の表記法、r"{...}"r"[...]" を使い、

ex_string <- r"{raw stringリテラルは r"(Hoge\Hoge\Hoge)"のように表記します}"
cat(ex_string,"\n")

とします。とにかく、違う形で囲めば良いので、

ex_string <- r"[raw stringリテラルは r"(Hoge\Hoge\Hoge)"、あるいは、r"{Hoge\Hoge\Hoge}"のように表記します]"
cat(ex_string,"\n"

のような場合も対応できます。全部使いたい場合は、別々に定義して、結合してください。

printcatで表示が違う

 上の例で、printを使って、original_Win_pathを表示すれば、エスケープ文字が追加されて、"\"は"\\""として表示されます。

> print(original_Win_path)
[1] "D:\\Document\\AAA\\BBB\\CCC\\DDD\\EEE\\FFF\\GGG\\HHH"

 また、catを使えば、"\"はそのまま表示されます。

> cat(original_Win_path,"\n")
D:\Document\AAA\BBB\CCC\DDD\EEE\FFF\GGG\HHH

Rのエスケープシーケンス

 上では、バックスラッシュ"\"をエスケープ文字として扱わない方法を紹介しました。それに対し、エスケープ文字として扱う方法についてもまとめておきます。

 以下に、R の文字列内で使える主なエスケープシーケンスをまとめました。各シーケンスは、特定の文字や制御文字を表現するために使われます。

エスケープ文字列 説明
\\ バックスラッシュそのもの(\
\" ダブルクォート(")
\' シングルクォート(')
\n 改行(ニューライン)
\r 復帰(キャリッジリターン)
\t 水平タブ(タブ文字)
\b バックスペース
\a 警告音(ベル)
\f 改ページ(フォームフィード)
\v 垂直タブ
\ooo 8進数表現(1~3桁の8進数で文字指定)
\xhh 16進数表現(1~2桁の16進数で文字指定)
\uXXXX Unicode 表現(4桁の16進数)
\UXXXXXXXX Unicode 表現(8桁の16進数)

Rでの実例を以下に示しておきます。

# バックスラッシュそのものを表示(\\)
cat("バックスラッシュ: \\\n")

# ダブルクォートを表示(\")
cat("ダブルクォート: \"\n")

# シングルクォートを表示(\')
cat("シングルクォート: \'\n")

# 改行を表示(\n)
cat("改行の例:\n1行目\n2行目\n")

# 復帰を表示(\r)
# ※環境により挙動が異なる場合があります
cat("復帰の例: Hello\rWorld\n")

# 水平タブを表示(\t)
cat("タブの例: 列1\t列2\t列3\n")

# バックスペースを表示(\b)
cat("バックスペースの例: ABC\bD\n")

# 警告音(ベル)を表示(\a)
cat("ベル音の例: \a\n")

# 改ページ(フォームフィード)を表示(\f)
cat("改ページの例: Page1\fPage2\n")

# 垂直タブを表示(\v)
cat("垂直タブの例: Vertical\vTab\n")

# 8進数表現(例: \101 は 'A' を表す)
cat("8進数表現の例: \101\n")

# 16進数表現(例: \x41 は 'A' を表す)
cat("16進数表現の例: \x41\n")

# Unicode 4桁表現(例: \u03B1 はギリシャ文字の α を表す)
cat("Unicode (4桁) の例: \u03B1\n")

# Unicode 8桁表現(例: \U000003B1 は同じく α を表す)
cat("Unicode (8桁) の例: \U000003B1\n")