Rのエラーを直して覚える
実際に出力されるメッセージを読みながら、空欄を埋めて直します。全165問。間違えた問題は翌日・3日後・7日後に自動で再出題されます。
今のエラーメッセージで探す
コンパイラや実行時に表示されたメッセージをそのまま貼り付けてください。行番号や変数名が違っても見つかります。
エラー別に調べる
初級
- 括弧の閉じ忘れによる構文エラーの原因と直し方関数呼び出しの丸括弧を閉じ忘れると、Rはどこまでが引数なのか判断できず、次の行のコードまで読み込み続けた末に構文エラーになります。
- 文字列の閉じクォート忘れによる構文エラー文字列を囲むクォートの片方を書き忘れると、それ以降のコードすべてが文字列の中身として読み込まれ続け、閉じクォートが見つからないまま構文エラーになります。
- c() のベクトルリテラルでカンマを付け忘れたときの構文エラーc()で要素を並べる際、区切りのカンマを付け忘れると、次の要素が予期しないトークンとして構文エラーになります。
- if の条件式に = を書くと構文エラーになる(比較は == が必要)if()の条件の中に==の代わりに=を書くと、Rはそれをif自体への名前付き引数の指定と解釈しようとして構文エラーになります。
- Error: object 'x' not found の原因と直し方宣言・代入していない名前を参照したときに出るエラーです。変数名のタイプミスのほか、代入する前に参照してしまったときにも起こります。
- could not find function "x" の原因と直し方存在しない名前の関数を呼び出したときに出るエラーです。関数名を1文字でも間違えると、Rは似た名前を推測して実行してはくれず、その場でエラーになります。
- 文字列と数値を + で連結すると non-numeric argument エラーになるRの+演算子は数値同士専用で、文字列を連結する演算子ではありません。文字列と数値を+でつなごうとすると、暗黙の型変換が行われずエラーになります。
- if (NA > 1) が missing value where TRUE/FALSE needed になる理由NAを含む式をif()の条件に使うと、真偽が定まらないため「missing value where TRUE/FALSE needed」というエラーで止まります。
- argument is missing, with no default の原因と直し方関数が必要とする引数を渡し忘れると、デフォルト値が定義されていない限りこのエラーになります。
- unused argument の原因と直し方関数が受け取れる数より多い引数を渡すと、余分な引数が「使われない引数」としてエラーになります。
- リストの [[ ]] で範囲外アクセスすると subscript out of bounds になるリストに対して[[ ]]で存在しない添字を指定すると、subscript out of boundsというエラーになります。ベクトルの[ ]と違い、[[ ]]は範囲外を静かに見逃しません。
- ベクトルの範囲外アクセスはエラーにならず NA を返す存在しない添字でベクトルにアクセスしても、Rはエラーを出さずNAを返すだけです。その後NAを使った計算をすると、結果全体がNAとして伝播します。
- / は整数同士でも常に小数を返す(%/% との違い)Rの/演算子は、両辺が整数であっても常に小数(浮動小数点数)を返します。商の整数部分だけが欲しい場合は%/%を使う必要があります。
- Rscript では代入や式の結果が自動では表示されない対話コンソールと違い、Rscriptで実行するスクリプトでは代入文の結果は表示されません。値を画面に出したい場合は明示的にprint()やcat()を呼ぶ必要があります。
中級
- 長さの合わないベクトル同士の演算は警告付きで再利用(リサイクル)される長さの異なるベクトル同士を+などで演算すると、短い方のベクトルが先頭から繰り返し使われて長さを揃えます。長い方が短い方の倍数でない場合は警告が出ますが、それでも計算自体は止まらず結果が返ります。
- 関数内の <- による代入はグローバル変数を変更しない関数の中で<-を使って外側と同じ名前の変数に代入しても、それは関数内だけのローカル変数を新しく作るだけで、外側のグローバル変数には影響しません。外側の変数を書き換えたい場合は<<-を使う必要があります。
- sapply は結果を勝手に行列へ簡略化することがあるsapplyは各要素の計算結果が同じ長さのベクトルであれば、リストではなく行列に自動的にまとめてしまいます。1個の値だけを期待していたコードが、複数要素を返す関数を渡した途端に行列を受け取ることになります。
- == で NA と比較すると NA が返り FALSE にはならないNAを含む式を==で比較すると、結果はTRUEでもFALSEでもなくNAになります。「等しくない」ことを確認したいつもりでNAと比較しても、判定自体ができません。
- リストの [ ] は要素そのものではなく部分リストを返す([[ ]] との違い)リストに対して[ ]でアクセスすると、中身の値そのものではなく、その要素だけを含む部分リストが返ります。中身の値を直接取り出したい場合は[[ ]]を使う必要があります。
- non-conformable arguments の原因と直し方(行列の次元不一致)行列の掛け算%*%は、左の行列の列数と右の行列の行数が一致していないと計算できません。次元が合わないとnon-conformable argumentsというエラーになります。
- 1:length(x) は x が空ベクトルのとき 1 と 0 の2回ループしてしまう1:length(x)はxが空ベクトル(長さ0)のとき1:0、つまりc(1, 0)という降順の数列になります。空のはずのループが2回実行され、存在しない添字xでのアクセスが発生します。
- 引数名の部分マッチにより意図しない引数に値が渡ることがあるRの名前付き引数は、他の引数名と衝突しない範囲で省略して書けます(部分マッチ)。似た名前の引数が複数ある関数で省略して書くと、意図と違う引数に値が渡ってしまうことがあります。
- 順序なし factor を < や > で比較すると警告付きで NA になるfactor型の値は、順序を持たない通常のfactorのままだと< や >のような大小比較ができず、'not meaningful for factors'という警告とともにNAになります。大小関係のある比較をしたい場合は、factor()の時点でordered = TRUEを指定しておく必要があります。
- sapply に渡す関数へ追加引数を渡し忘れると missing エラーになるsapply(x, f, ...)の...部分に追加引数を渡し忘れると、fの2つ目以降の必須引数が埋まらず、argument is missingエラーになります。
- which() の戻り値と論理ベクトルによる添字指定を混同するとずれるwhich(条件)は条件を満たす要素の「位置(添字番号)」を返しますが、条件そのもの(論理ベクトル)を直接添字として使うのとは意味が違います。which()の結果をさらに論理ベクトルとして使うと、位置の数値がTRUE/FALSEとして解釈され、意図と違う要素が選ばれます。
上級
- S3の print メソッドで NextMethod() を省略すると基底クラスの表示が失われるS3クラスに独自のprint.myclassを定義するとき、NextMethod()を呼ばずに独自の出力だけを書くと、継承元のクラスが本来表示していた情報が完全に失われます。
- environment はベクトルと違い参照渡しのように振る舞うRのベクトルやリストは関数に渡すと複製され、関数内での変更は呼び出し元に影響しません。一方environmentは参照として渡されるため、関数内でその中身を書き換えると呼び出し元のenvironmentにもその変更が反映されます。
- 関数名を直接書いた再帰呼び出しは、関数を別名に代入し直すと壊れる再帰関数の中で自分自身を関数名で直接呼び出していると、その関数を別の変数名に代入し直して元の名前を消した途端、再帰呼び出しの箇所がobject not foundエラーになります。名前に依存せず自分自身を参照したい場合はRecall()を使う必要があります。
- do.call に渡すリストの名前が引数名と一致しないと unused argument になるdo.call(f, args)は、argsという名前付きリストの各要素名をfの引数名として渡します。リストの要素名が関数の引数名と1文字でも違うと、その引数は認識されず「使われない引数」としてエラーになります。
- match.arg に候補外の値を渡すと 'arg' should be one of エラーになるmatch.arg()で選択肢を制限した引数に、定義された候補のどれとも一致しない値を渡すと、'arg' should be one ofというエラーになります。
- Reduce に init を渡さず空ベクトルを渡すと NULL が返り後続処理でエラーになるReduce(f, x)はinitを省略した状態でxが空ベクトルだと、畳み込みを始める最初の値が無いためエラーにはならずNULLを返します。そのNULLをif()の条件などにそのまま使うと、そこで初めて「argument is of length zero」というエラーになります。
- vapply は FUN.VALUE のひな形と実際の戻り値の型・長さが違うとエラーになるvapplyはFUN.VALUEに渡したひな形と、実際に関数が返す値の型や長さが厳密に一致しないとエラーになります。sapplyのように結果の形を黙って合わせてはくれません。
- tryCatch の error ハンドラは warning を捕まえないtryCatch(expr, error = function(e) ...)のerrorハンドラは、条件クラスがerrorであるものしか捕まえません。warning()で発生させた警告は、実行が止まらないままerrorハンドラをすり抜けます。