2016-04-01 20 views
1

複数行の文字列引数を使用してコマンドラインからRを外部で呼び出すとき、誰もこの動作を説明できますか?Rscript -eコールの割り当て問題

$ Rscript -e "dim(mtcars)" 
[1] 32 11 
$ Rscript -e "df = mtcars; dim(df)" 
[1] 32 11 
$ Rscript -e "head(rownames(mtcars))" 
[1] "Mazda RX4"   "Mazda RX4 Wag"  "Datsun 710" 
[4] "Hornet 4 Drive" "Hornet Sportabout" "Valiant" 
$ Rscript -e "df = mtcars; df$car = rownames(mtcars); dim(df)" 
NULL 
+1

マイナーポイント:「複数行の文字列引数」ではなく「マルチステートメント文字列引数」と呼ぶのが正しいでしょう。 – bgoldst

答えて

4

ここで犯人はあなたが使用しているもののシェルを示し、それらはすべて(SH/bashの/灰/ダッシュ/ kshの/ zshの/ tcshのいないシェルではなく、R.

)我々の目的のためにかなり同様に動作するので、あなたはbashのを使用していると仮定しましょう、私は半分bash man pageを引用することができます

...

定義

       以下の定義は、この文書の残りの部分で使用されます。

...

                       単語英数字とアンダースコアのみからなる、アルファベット文字またはアンダースコアで始まります。識別子とも呼ばれます。

...

を引用

...二重引用符で文字を囲む

       は `、$を除いて、全ての文字のリテラル値を保持します、\、履歴展開が有効な場合は!文字$と `は二重引用符で囲まれた特殊な意味を保持します。

...

PARAMETERS

       パラメータは、値を格納するエンティティです。 の名前、数字、または特殊パラメータの下にリストされている特殊文字のいずれかになります。変数は、という名前のパラメータで、です。

...

       パラメータ展開

                `$」文字は、パラメータ展開、コマンド置換、または算術展開を紹介しています。展開されるパラメータ名またはシンボルは、省略可能な中括弧で囲むことができますが、名前の一部として解釈できる直後の文字から展開する変数を保護する役割を果たします。

...

        $ {パラメータ}

               パラメータの値が代入されます。中かっこは、parameterが2桁以上の位置パラメータである場合、またはパラメータの後にその名前の一部として解釈されない文字が続く場合に必要です。パラメータは、上記のようなシェルパラメータ(パラメータ)または配列参照(配列)です。

...

ので、パラメータ展開は、二重引用符で囲まれた文字列の中に有効になり、そしてあなたは、二重引用符で囲まれた文字列で有効な変数名が続くエスケープドル持っている:$carを。

違反コマンドを実行したシェルセッションで変数$carが設定されていないと推測します。

シェルの残念なデフォルトの動作は、未設定の変数を空の文字列にサイレント展開することです。したがって、あなたのRコードはこのに台無しにされてしまう:

df = mtcars; df = rownames(mtcars); dim(df) 

したがってdfは無次元文字ベクトルで上書きされ、このようなベクターにdim(df) NULLを返します。単一引用符で囲まれた文字列内の場所を取るために任意の補間を許可していない単一引用符を使用して、まだ

Rscript -e "df <- mtcars; df\$car <- rownames(mtcars); dim(df);"; 
## [1] 32 12 

またはそれ以上:

問題は、バックスラッシュエスケープドルをすることによって解決することができます。個人的なノートで

Rscript -e 'df <- mtcars; df$car <- rownames(mtcars); dim(df);'; 
## [1] 32 12 

、IMO、非常に少数のエンジニアは厳密の重要性を理解するように見えますソフトウェア設計ではです。それは、シェルが1日目から設定されていない変数を拒否するように設計されていたコンピュータプログラミング専門家には素晴らしいサービスでしたが、悲しいかな、そうではありません。あなたと私のような貧しい人々、そして基本的にシェルプログラミングをしている人は、時々これらの静かな間違いにぶつかります。

幸い、オプション機能がnounsetと呼ばれる上、早期シェルに追加されました:

help set| grep -e nounset -e -u; 
##    nounset  same as -u 
##  -u Treat unset variables as an error when substituting. 

あなたがそれをオンにした場合、私はあなたが、その後、問題Rscriptコマンドはすぐに失敗しただろうか強く示唆ました

set -u; 
Rscript -e "df <- mtcars; df$car <- rownames(mtcars); dim(df);"; 
## -bash: car: unbound variable 
+2

正解であり、きれいに詳細です。要するに、 ''は補間の欠如のためにあなたの友人です。 –

+1

素敵な仕事bgoldst - bashの錬金術は正式に暴行した.. – geotheory

関連する問題