このページでは,

 R FAQ
 Frequently Asked Questions on R
 Version 1.7-27, 2003-07-16
 ISBN 3-901167-51-X
 Kurt Hornik

(http://cran.r-project.org/doc/FAQ/R-FAQ.html ) の第 7章の日本語訳に取り組みます.


R-FAQ 日本語訳全体の目次


7. R について雑多なこと (R Miscellanea)


7.1 R がメモリー不足になるのはなぜでしょうか? (Why does R run out of memory?)

1.2.0 より前のヴァージョンの R は, 静的メモリー・モデルを使っていました. R は, 起動時に OS に対して, ある固定した量のメモリーを確保するように要求していました. その確保したメモリーのサイズは, 起動後には変更することができませんでした. そのため, たとえば, 大きいデータセットを R に読み込もうとした場合などに, じゅうぶんなメモリーを割り当てられなくなることがありました. そのような場合には, もっと多くのメモリーを利用できるように (コマンド・ラインオプション --nsize と --vsize で) 設定して, R を再起動する必要がありました.

R ヴァージョン 1.2.0 で, 新しい "世代別 (generational)" ガーベジ・コレクターが導入されました. それは, R が利用できるメモリーを必要なサイズだけ増加させます. そのため, じゅうぶんなメモリーを利用できるようにユーザーが介入する必要はなくなりました.

この新しいガーベジ・コレクターはメモリー内のオブジェクトを移動させません. つまり, 使われていないメモリーが断片化されてしまい, その結果, 明らかにじゅうぶんなメモリーがあるにも関わらず大きいオブジェクトが割り当てられなくなる可能性があります.

7.2 正しいソース・ファイルの読込みに失敗するのはなぜでしょうか? (Why does sourcing a correct file fail?)

1.2.1 より前のヴァージョンの R では, 改行で終わっていないファイルの構文解析に問題があったかもしれません. より初期のヴァージョンでは, データ・ファイルを読み込むときにも同様の問題がありました. この問題はもはや発生しないはずです.

7.3 リストの要素を NULL にセットするには? (How can I set components of a list to NULL?)

 x[i] <- list(NULL)

を用いると, リスト x の要素 i に NULL をセットすることができます. 名前付きの要素についても同様です.

x[i] あるいは x[ [i] ] に NULL をセットしないでください. これは, リストから該当する要素を削除してしまいます.

行列 x の行に付けられた名前をすべて落とすには, rownames(x) <- NULL を用いると簡単かもしれません. 列に付けられた名前をすべて落とす場合も同様です. { colnames(x) <- NULL }

7.4 自分のワークスペースを保存するには? (How can I save my workspace?)

save.image() は, R を起動したディレクトリー内のファイル .RData に, ユーザーの .GlobalEnv 内のオブジェクトを保存します (これは, q("yes") の後で起こることと同じです). save.image(file) を用いれば, file という名前のファイルに保存することができます.

7.5 自分のワークスペースを一掃するには? (How can I clean up my workspace?)

 rm(list = ls(all = TRUE))

を実行すると, 現在のアクティヴな環境 (一般に .GlobalEnv) におけるすべてのオブジェクトを削除することができます. (all = TRUE なしの場合は, ドット (.) で始まらない名前のオブジェクトだけ削除されます.)

7.6 eval() と D() を機能させるには? (How can I get eval() and D() to work?)

eval(print(x), envir = e) あるいは D(x^2, "x") { D() は所定のシンボルについて第 1引数を微分する関数 } を用いると変なことが起こります. eval(print(x), envir = e) では, "x" が見つからないと言われるか, あるいは, 間違った x の値が出力されます. D(x^2, "x") についてはおそらく, x が存在する場合は 0 を, 存在しない場合はエラーを返すでしょう.

これは, どちらの関数でも, 第 1引数が最初に, その関数を呼び出した環境において評価されるために起こります. その評価結果 (モードが「表現式」 ("expression") あるいは「関数呼出し」 ("call") のオブジェクトになっている必要があります) が, その後で, 評価あるいは微分されます. あなたが (おそらく) ほんとうに欲しい結果は, 第 1引数を expression() で「クォートする」ことによって得られます. たとえば,

 R> D(expression(x^2), "x")
 2 * x

この挙動は, 最初はかなり変に見えるかもしれませんが, 完全に論理的です. 「直感的な」挙動のほうが実装しやすいかもしれませんが, 表現式が変数の中に含まれ, それがパラメーターとして渡される場合や, あるいは, 関数呼出しの結果である場合はいつでも問題が生じることになります. たとえば, 下記のような場合にその意味を考察してみてください:

 D2 <- function(e, n) D(D(e, n), n)

あるいは

 g <- function(y) eval(substitute(y), sys.frame(sys.parent(n = 2)))
 g(a * b)

{ 関数 g の変数の中に eval(...) が含まれ, パラメーターとして渡される例. }

さらに別の実行例については deriv() の help ページをご参照ください.

7.7 行列の次元がなくなることがあるのですがなぜでしょうか? (Why do my matrices lose dimensions?)

単一の行あるいは列を持つ行列を, 添字指定演算 (たとえば, row <- mat[2, ]) によって生成する場合, ディフォールトでは行列がベクトルに変わります. 同様に, 多次元配列 (たとえば, 2 x 3 x 1 x 4 の配列) を添字指定によって生成すると, 不要な次元がなくなって, 2 x 3 x 4 の配列に強制的に変わります. 多くの議論の後, これは仕様であると決定されました.

これが起こらないようにするには, オプション drop = FALSE を付けます. たとえば,

 rowmatrix <- mat[2, , drop = FALSE]  # 2行 1列の行列を生成します
 colmatrix <- mat[, 2, drop = FALSE]  # 1行 2列の行列を生成します
 a <- b[1, 1, 1, drop = FALSE]        # 1 x 1 x 1 の配列を生成します

プログラミングの際に, 安全のためにこの drop = FALSE オプションを用いるほうが良いでしょう. たとえば, ステートメント

  somerows <- mat[index, ]

は, index がたまたま長さ 1 であると, 行列ではなくベクトルを返しますが, これはコードの別のところでエラーの原因になるかもしれません. たぶん, つぎのように書き直すほうが良いでしょう:

  somerows <- mat[index, , drop = FALSE]

7.8 オートロードはどのように機能するのでしょうか? (How does autoloading work?)

R には, .AutoloadEnv という特別な環境があります. autoload(name, pkg) を用いると, ある種の情報をこの環境に格納します. ここで, name はオブジェクトの名前を, pkg はそのオブジェクトが入っているパッケージ名を表わす文字列です. R が name の評価を試みるとき, その該当するパッケージ pkg をロードし, その新しいパッケージの環境において name を再び評価します.

この仕組を用いると, R は, メモリーを (まだ) 占有していないのに, そのパッケージがロードされたかのように挙動します.

autoload() の help ページに非常に良い実行例があるので, ご参照ください.

7.9 オプションはどのようにセットすれば良いでしょうか? (How should I set options?)

関数 options() を用いると, R の計算方法や計算結果の表示方法に影響を与える様々なグローバル「オプション」を設定したり, 調べたりすることができます. 変数 .Options がこれらのオプションの現在の値を保持しますが, 気が狂いたくなければ, この変数の値を直接いじるべきではありません -- ただ単に, 「読み出し専用の」変数ということにしておいてください.

たとえば,

 test1 <- function(x = pi, dig = 3) {
   oo <- options(digits = dig); on.exit(options(oo));
   cat(.Options$digits, x, "\n")
 }
 test2 <- function(x = pi, dig = 3) {
   .Options$digits <- dig
   cat(.Options$digits, x, "\n")
 }
   

を与えたとき, 下記の実行結果が得られます:

 R> test1()
 3 3.14
 R> test2()
 3 3.141593

実際に用いられるのは, .Options のグローバル値です. そして, options(OPT = VAL) を用いることでその値を正しく更新します. .Options のローカルなコピーは, .GlobalEnv の中であれ, ある関数の環境 (フレーム) の中であれ, ただ黙って無視されるだけです.

7.10 Windows においてファイル名はどのように機能するのでしょうか? (How do file names work in Windows?)

R は C-スタイルの文字列操作を用いるので, バックスラッシュあるいは円記号 (\) はエスケープ文字として扱われます. そのため, たとえば, 改行は \n と書くことができます. バックスラッシュあるいは円記号自体が必要な場合は, バックスラッシュあるいは円記号自体をもう 1つのバックスラッシュあるいは円記号でエスケープする必要があります. { \\ のように. }

したがって, ファイル名では "c:\\data\\money.dat" のような書き方を用いてください. バックスラッシュあるいは円記号 (\) をスラッシュ (/) に置き換えることもできます ("c:/data/money.dat").

7.11 プロットを実行すると色の割当てエラーが起こるのはなぜでしょうか? (Why does plotting give a color allocation error?)

プロット (たとえば, demo("image") など) を実行したときに, ときどき, "Error: color allocation error" になることがあります. これは X ウィンドウ・システムの問題であり, R には間接的にしか関係しません. これは, R より前に起動したアプリケーションが利用可能な色をすべて使ってしまった場合に起こります. (利用可能な色数は X の設定によります; ときに, 256色しか使えない場合があります.)

色を「食べてしまう」ことで悪名高いアプリケーションの 1つが Netscape です. もしも, Netscape が動作しているときにこの問題が起こるならば, Netscape に -no-install (ディフォールトのカラーマップを使う) か, あるいは -install (プライヴェート (個別の) カラーマップを使う) オプションを付けて再起動してみてください.

また, X11() のカラータイプを, ディフォールトの "pseudo" ではなくて, "pseudo.cube" にセットできるかもしれません. より詳しい情報については X11() の help ページをご参照ください.

7.12 因子を数値に変換するには? (How do I convert factors to numeric?)

R に数値データを読み込むとき (通常, ファイルから読み込むとき), その数値データが 因子 (factor) として読み込まれることがあるかもしれません. f がそのような因子オブジェクトであるとき, 次式でデータを数字に戻すことができます:

 as.numeric(as.character(f))

もっと効果的な (だが, 覚えにくい) 式は,

 as.numeric(levels(f))[as.integer(f)]

です.

どのような場合でも, as.numeric() あるいはそれに類するものを直接呼び出さないでください.

7.13 Trellis 表示は R に実装されていますか? (Are Trellis displays implemented in R?)

{ Trellis 表示: 横軸が共通の変数で, 縦に異なる変数のグラフを並べて表示する方法 }

推奨パッケージ lattice (これはまた別の推奨パッケージ grid に基づいている) は, Trellis コマンド群の大部分と互換なグラフィクス機能を提供します.

また, あなたが (Trellis 表示で) したいことの少なくともいくつかはできそうなので, coplot() および dotchart() を見ておくと良いかもしれません.

注. pairs() の R ヴァージョンはかなり一般的で, splom() の機能の大部分を提供します. また, R のディフォールトのプロット手法には asp という引数があり, プロットの縦横比を指定すること (および, デバイスのサイズ変更に影響を受けないように縦横比を固定すること) ができます.

("Trellis" という語は商標として請求されているので, R ではこの語を用いません. R での同等物には「格子」 ("lattice") という名前が選ばれています.)

7.14 囲み環境および親環境とは何でしょうか? (What are the enclosing and parent environments?)

関数の内部で, 2種類の付加的な環境の変数にアクセスしたいことがあります: 1つは, その関数が定義されたところの環境 ("囲み"), もう 1つは, その関数を呼び出したところの環境 ("親") です.

もしも, ある関数をコマンド・ライン上で生成するか, あるいは関数をパッケージ内にロードするならば, その関数の囲み環境はグローバル・ワークスペースです. もしも, ある関数 f() を別の関数 g() の内部で定義するならば, 関数 f() の囲み環境は g() の内部の環境になります. ある関数の囲み環境は, その関数が生成されたときに固定されます. 関数 f() の囲み環境は, environment(f) を用いて調べることができます.

それに対して, "親" 環境は, 関数が呼び出されるときに定義されます. もしも, lm() がコマンド・ライン上で呼び出されたときは, その親環境はグローバル・ワークスペースです. もしも, lm() がある関数 f() の内部で呼び出されたときは, その親環境は f() の内部の環境になります. ある関数の呼出しに対する親環境は, parent.frame() あるいは sys.frame(sys.parent()) を用いて調べることができます.

したがって, ユーザーに見える関数の大部分で, その囲み環境はグローバル・ワークスペースになるでしょう. というのは, グローバル・ワークスペースで大部分の関数が定義されるからです. 関数が呼び出されるところならばどこでも, その関数の親環境になるでしょう. もしも, ある関数 f() が別の関数 g() の内部で定義されているならば, おそらく f() は g() の内部で用いられるでしょう. その場合, 関数 f() の親環境と囲み環境は同一になります.

(関数が呼び出された環境において変数が利用できる) モデル式のような事物は, その関数が呼び出された環境で評価される必要があるので, 親環境は重要です. これは, 呼出しの度に異なる可能性のある親環境に依存します.

関数によっては, 他の関数や自分自身の他の呼出しとの間で情報を共有する (レキシカル・スコープのセクション参照) ために, 囲み環境における変数を用いるかもしれないので, 囲み環境は重要です. これは, 関数が呼び出される度に同一な囲み環境に依存します.

スコープ (有効範囲) は難解です. 実例を眺めることが助けになります. R と S で異なって機能する実例を眺めて, なぜ両者が異なるのか理解しようと試みることはとくに有益です. R と S の間のスコープの違いについての 1つの言い方は, S では囲み環境はつねにグローバル・ワークスペースであるに対して, R では囲み環境はその関数が生成された場所であるということです.

7.15 プロットのラベルに値を代入するには? (How can I substitute into a plot label?)

プロットのラベル (たとえば, タイトル) に R のオブジェクトの値を用いたい場合があります. ラベルが単純な文字列の場合は, paste() を用いて簡単に実現できます. しかし, ラベルが (洗練された数式用注釈の) 表現式の場合は, つねに明白であるとは限りません. そのような場合, ペーストした文字列には parse() を, 表現式には substitute() を用いてください. たとえば, ahat が分析対象であるパラメーター a の推定量であるとき,

 title(substitute(hat(a) == ahat, list(ahat = ahat)))

を用いてください (= ではなく, == になっていることに注意). メーリング・リストのアーカイヴにはもっと工夫された例があります.

7.16 正当な名前は何でしょうか? (What are valid names?)

data.frame() あるいは read.table() を用いてデータ・フレームを生成するとき, R はディフォールトで, 変数名が構文的に正当であることを確保します. (これらの関数の引数 check.names は, 必要ならば make.names() で変数名を点検・調整するかどうかコントロールします.)

どのような名前が "正当" であるか理解するには, R 言語では "名前" という用語が, 下記のようにいくつかの異なる (けれども関連する) 様式で用いられていることを考慮する必要があります:

  1. 構文名とは, 構文解析器がこの型の表現として解釈する文字列です. 構文名は, アルファベット文字, 数字, およびドット (.) で構成され, アルファベット文字あるいはドット (.) で始まります.
  2. オブジェクト名とは, 表現式において割り当てられるオブジェクトに関連づけられた文字列です. 関連づけは, 代入操作 (assignment operation) の左辺にオブジェクト名を置くか, assign() 関数の引数として与えます. オブジェクト名は通常, 構文名ですが, クォートすれば, 空でない任意の文字列が可能です (そして, assign() への呼出しのときは, つねにクォートします).
  3. 引数名とは, 関数呼出しにおいて引数を与える場合に, 等号の左側に現れるものです (たとえば, f(trim=.5)). 引数名は通常, 構文名ですが, クォートすれば任意の文字列が可能です.
  4. 要素名とは, オブジェクトの構成要素 (たとえば, リストの要素) を識別する文字列です. 要素名が $ 演算子の右側で用いられるときは, 構文名を満たしているかあるいはクォートされなければなりません. それ以外の場合は, 要素名は任意の文字列が可能です. (eval() あるいは attach() への呼出しにおけるように, オブジェクトがデータベースとして用いられる場合は, 要素名がオブジェクト名になります.)
  5. そして最後に, ファイル名とは, OS においてファイルを読み書き等のために識別する文字列です. ほんとうは, R 言語における名前とはあまり関係がないのですが, これもファイル "名" と呼ぶのが伝統的です.

7.17 一般化加法モデル (GAMs) は R に実装されていますか? (Are GAMs implemented in R?)

パッケージ mgcv には一般化加法モデル (Generalized Additive Models) のための gam() 関数がありますが, White Book { "Statistical Models in S" のこと } に記述されたものの完全なクローンになっていません (たとえば, lo() がないなど). パッケージ gss がスプライン‐ベースの GAMs に合わせることができます. また, 回帰スプラインで良ければ, glm() を用いることができます. ガウス型 GAMs については, パッケージ mda の bruto() を用いることができます.

7.18 あるファイルについて source() を実行したとき, その結果が出力されないのですが, なぜでしょうか? (Why is the output not printed when I source() a file?)

R コマンドの大部分は何も出力しません. コマンド

 1+1

は値 2 を計算し, その値を返します. コマンド

 summary(glm(y~x+z, family=binomial))

は, ロジスティック回帰モデルの当てはめを行い, ある種の要約情報を計算し, クラス "summary.glm" のオブジェクトを返します (「要約の手法はどのように書けば良いでしょうか?」 (How should I write summary methods?) 参照).

もしも, 1+1 あるいは summary(glm(y~x+z, family=binomial)) をコマンド・ラインでタイプしたのならば, (invisible() を実行していなければ) その返り値は自動的に出力されます. しかし, コマンド・ライン以外の状況, たとえば source() されるファイルや関数の中では, 特別に出力コマンドを書かないかぎり, 実行結果は出力されません.

ファイルに対して source() を実行した結果を出力するには,

 print(1+1)

あるいは

 print(summary(glm(y~x+z, family=binomial)))

を用いるか, あるいは, source(file, echo=TRUE) を用いてください.

7.19 ある関数について outer() を実行すると挙動が変なのですがなぜでしょうか? (Why does outer() behave strangely with my function?)

outer() の help が示すように, apply() ファミリーのようにどの関数でも機能するわけではありません. 関数は, 配列上の要素毎に機能するようにベクトル化されている必要があります. outer() のコードを見ると分かるように, outer(x, y, FUN) は, x と y の要素のあらゆる組合せで構成される 2つの大きいベクトルを生成してから, そのベクトルをすべて一挙に FUN に渡します. おそらく, 問題の関数は, 2つの大きいベクトルをパラメーターとして扱えないのでしょう.

2つのベクトルは扱えないけれども, 2つのスカラーは扱うことのできる関数については, ベクトル化された振舞いをシミュレートするラッパー関数を用意することにより, outer() を使えるようになります.

たとえば, outer() を実行したい関数が,

 foo <- function(x, y, happy) {
   stopifnot(length(x) == 1, length(y) == 1) # スカラーのみ!
   (x + y) * happy
 }

であるとします. 汎用関数

 wrapper <- function(x, y, my.fun, ...) {
   sapply(seq(along = x), FUN = function(i) my.fun(x[i], y[i], ...))
 }

を定義すれば, つぎのように書くことにより, outer() を用いることができます:

 outer(1:4, 1:2, FUN = wrapper, my.fun = foo, happy = 10)

7.20 anova() の出力結果がモデルにおける因子の順序に依存するのはなぜでしょうか? (Why does the output from anova() depend on the order of factors in the model?)

A+B+A:B のようなモデルでは, R は ~1, ~A, ~A+B および ~A+B+A:B の間の 2乗和の差をレポートすることになります. もしもモデルが ~B+A+A:B ならば, ~1, ~B, ~A+B, および ~A+B+A:B の間の (2乗和の) 差をレポートすることになります. 最初の例では, A に関する 2乗和は ~1 および ~A を比較していますが, 2番目の例では, ~B および ~B+A を比較しています. 非直交型のデザイン (つまり, 不均衡デザインの大部分) では, これらの比較は (概念的にも数値的にも) 異なります.

パッケージによっては, モデル全体と各因子を 1つずつ除いたモデル群との比較に基づく 2乗和をレポートするものもあります (たとえば, SAS の有名な「タイプ III の 2乗和」がそうです). このようなパッケージはモデルにおける因子の順番に依存しません. どちらの 2乗和の取り方が正しいのかという質問は, ときどき r-help で低レヴェルの聖戦を引き起こしています.

R がレポートする特定の 2乗和について動揺する必要はありません. まったく簡単に, お気に入りの方法で 2乗和を計算することができます. anova(model1, model2) で, 任意の 2つのモデルを比較することができ, また, drop1(model1) によって 単一の項目を落とした後の 2乗和を示すことができます.

7.21 バッチ・モードで PNG グラフィクスを生成するには? (How do I produce PNG graphics in batch mode?)

Unix では, png() デバイスは X11 ドライヴァーを用いますが, これがバッチ・モードあるいはリモート操作では問題になります. システムに Ghostscript がインストールされているならば, bitmap() を用いて PNG を生成することができます. bitmap() は, PostScript を生成して, それから, ghostscript がサポートする任意のビットマップ形式に変換します. インストール状態によっては, この方法では汚い出力にしかならないものもあるし, 完全に満足いく出力になるものもあります. 理論上は, Xvfb を用いると (PNG の生成が) 可能になるかもしれません. これは, ディスプレイなしの X サーヴァーを提供する機能です.

7.22 コマンド・ラインの編集を機能させるには? (How can I get command line editing to work?)

Unix における R とのコマンド・ライン・インターフェイスは, R のコンパイル設定 (configure) 実行時に GNU readline ライブラリーが利用可能になっているという条件で, コマンド・ライン・エディター機能を提供することができます. この機能は, 以前のコマンドの呼出し・編集・再実行を可能にします.

注. readline については, 適切なヘッダーをインクルードしている「開発」ヴァージョンが必要とされます. Linux バイナリー・ディストリビューションのユーザーの場合, libreadline-dev (Debian) あるいは readline-devel (Red Hat) のようなパッケージをインストールする必要があるでしょう.

7.23 文字列を変数に変換するには? (How can I turn a string into a variable?)

たとえば,

 varname <- c("a", "b", "d")

が与えられているとき,

 get(varname[1]) + 2

によって

 a + 2

に変換することができます. あるいは,

 assign(varname[1], 2 + 2)

によって

 a <- 2 + 2

に変換することができます. あるいは,

 eval(substitute(lm(y ~ x + variable),
                 list(variable = as.name(varname[1]))

によって

 lm(y ~ x + a)

に変換することができます.

少なくとも最初の 2つの例では, 単にリストを用いるほうが簡単な場合が多くて, そのときは, 名前でたやすくインデクスを付けることができます.

 vars <- list(a = 1:10, b = rnorm(100), d = LETTERS)
 vars[["a"]]

7.24 格子/Trellis のグラフィクスが機能しないのはなぜでしょうか? (Why do lattice/trellis graphics not work?)

もっともありそうな理由は, グラフを表示するように R に命令するのを忘れたというものです. 格子の関数群, たとえば xyplot(), はグラフ・オブジェクトを生成しますが, 表示は行いません (S-PLUS の Trellis のグラフィクスについても同じです). グラフ・オブジェクトの print() 手法が実際の表示を作ります. これらの(格子/Trellis) 関数群をコマンド・ラインで対話的に用いる場合は, 実行結果は自動的に表示されますが, source() や自作の関数の中では明示的に print() ステートメントを書く必要があるでしょう.

7.25 データ・フレームの行をソートするには? (How can I sort the rows of a data frame?)

データ・フレーム内の行を, 1つあるいはそれ以上の列の値でソートするには, ただ単に order() を用いてください.


{ 7章おわり }

最終更新日: 2003-08-05 (火) 22:31:39


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-03-25 (土) 11:19:16