| Top Page | プログラミング | R 自動化 目次 | 索引 | 前へ | 次へ |

R でプログラミング:データの一括処理とグラフ描き

4. グラフを描いてファイルに保存する

プログラムでグラフを描くメリット

データを表のまま眺めていたのでは,なかなか特徴はつかめません. まずはグラフを描いてじっくり吟味すると,おもしろいパターンが見えてくる かもしれません.

R は,統計解析関数が豊富に用意されているだけでなく,グラフを描く機能も充実しています. ごくごく簡単な命令で '適当に' 図を描いてくれる関数がある一方で, 細かいところまで思うままに制御して描画することも可能です. RjpWiki のページ一覧中の グラフィックス参考実例集 のあたりをあちこちながめると,じつに多彩なグラフが描けることが分かるでしょう. 地図だって描けます (たとえば Rmapを使った地図表示を参照).

プログラムで図を描くのは,マウスなどで手作業するのに比べて めんどうそうな気がします.でも,一度プログラムを書いてしまえば 何枚でも同じフォーマットで描けますし,たくさんのデータファイルを 一気に読み込んでグラフにしてしまうこともできます. また,データが変更されてもプログラム一発で再描画できます.

マウス手作業という選択肢だけでなく,プログラムで一括処理という 技術も持っていれば,状況に応じて効率が良いほうを選べます.

このページでは,簡単なグラフの描きかたと,描いたグラフをファイルに 保存する方法を紹介します. 実際に描きはじめるまえに,グラフの描画をはじめるまえに頭においておくとよいことを 3つだけ簡単に説明します.そんなことがあるのか,という程度に読み流してください.


予備知識を少々

予備知識1:高水準作図関数と低水準作図関数

R の作図関数のなかには,高水準作図関数と呼ばれるもの,低水準作図関数と呼ばれる ものがあります(このほかに対話的作図関数というものもありますが,ここでは とりあげません).

それぞれどんなものがあるかは,R-Tips の 高水準作図関数 低水準作図関数 などをちらっと眺めてみてください.

ひとことで言うと,高水準作図関数は自分で適当に考えてやってくれる関数, 低水準のほうは言われたことだけをやる関数という感じなのですが, もっとも重要な違いは,

ということです.つまり,高水準関数はそれ単独でグラフを描けるますが, 低水準関数は高水準関数で絵を描いたあと(あるいは他の方法で座標系を設定したあと) に重ね描きすることしかできません.このことは,次のページでくわしく説明します.


予備知識2:「総称的関数」

総称的というのは,いろんなものをまとめてひとつの名前で呼んでる,ということです. 総称的関数とは,実際には何種類もの関数があるのだけれど,それらをまとめて ひとつの名前で呼んでいるものです.

R にはいろいろな種類のオブジェクトがあります. データフレームとかベクトルとかいうのはその例です. 総称的関数に引数としてオブジェクトを渡すと,それがどんな種類の オブジェクトかに応じて,適当な(適切な,という意味)関数が呼び出されます.

もっとも基本的な作図関数は plotという関数ですが, これは総称的関数の例です. plotに引数としてオブジェクトを渡すと, 何十もの描画関数のなかからオブジェクトの種類に応じてひつとが選ばれ, 描画が行われます. つまり,どのような図が描かれるかは引数になにを渡すかによるのです. (※ 入力画面で methods("plot") と入力してみると, 名前が plot ではじまるたくさんの関数名が表示されます.これらのうちから 適切なものが選ばれ,呼び出されます).

このような柔軟な仕組みはとても便利です. 入力画面で試行錯誤しながら絵を描く場合は,まずはplotを 使ってみるのが常道です.

いっぽうで,オブジェクトを渡してみないとなにが起こるか分からないというのは, プログラムを書いて処理する場合にはあまり気持ちよくありません. こういうオブジェクトを渡すとこういう絵になるということを 確かめたうえでプログラムを書くことが必要です.


予備知識3:作図デバイス

R でにはグラフィック・デバイス(あるいは作図デバイス,あるいは単にデバイス) という概念があります.作図関数は,すべてこのデバイスに対して作用します. それぞれのデバイスには,こんな絵を書いてくれをいう命令をそのデバイスに合せて 実行してくれるデバイスドライバが用意されています. ふつうにR を起動して作図関数を呼び出すと,画面にグラフが表示されますが, これは画面描画を担当するデバイスドライバが用意され,描画の命令を実行してくれた結果です.

それ以外のデバイスを指定すると,さまざまな形式の画像ファイルを作ることができます. くわしくは,「グラフを画像ファイルに記録する」のところで説明します.


簡単なグラフをひとつ

前置きがずいぶん長くなりました.ここらでひとつ,とにかくグラフを書いてみましょう.

まずは plot でグラフを描く

前のページでも使ったデータをそのまま利用します.

d <- read.table('len_width.txt', header = TRUE) 

で,len_width.txt というファイル中のデータをデータフレームに読み込んだ 状態から作業します.作られたデータフレームのオブジェクトの名前は d です.

すでに説明したように,plotは渡されたオブジェクトの種類に応じて 賢くグラフを描いてくれる総称的関数です. 要素数が同じふたつのベクトルを渡すと,それぞれの値を縦軸,横軸にとって 散布分を書いてくれます. plotは高水準作図関数ですので,これだけ呼び出せば 適当に座標系(横軸,縦軸の範囲)を設定してグラフを描きます.

入力画面で

plot(d$len, d$width)

と入力してみてください.あたらしい画面が出てきて,散布図が描かれます (>グラフ).


さらに引数を与えてグラフの描き方を制御する

入力画面で help(plot)と入力すると分かるように,plot にはプロットする データ以外にもいくつかの引数を渡してグラフの描き方を指定することができます. R-Tips の plot() の形式指定 対数軸や軸の範囲の指定 タイトルなどの指定も参照してください.

たとえば,

plot(d$len, d$width, xlab = 'length (cm)', ylab = 'width (cm)')

のように,横軸,縦軸の説明を自由に設定することができます.

与える文字列が変数にしまわれているなら,変数名を与えます.

length.label <- 'Length (cm)'
width.label <-  'Width (cm)'
plot(d$len, d$width, xlab = length.label, ylab = width.label)

関数に与える引数は,すべてこのように,具体的な値(即値と呼んだりする)を 書き込むかわりに変数で指定できます.当たり前のことのようですが, このおかげでプログラムでできることの幅が飛躍的にひろがります.

<練習>

さらに,軸の最小値,最大値も設定してみます. 高水準作図関数であるplotは,縦軸,横軸とも適当な範囲に設定して くれますが,自分で制御したいこともあります. 次のページで説明するグラフの重ね描きとも密接に関連します.

横軸(x軸)の範囲は xlim,縦軸(y軸)の範囲は ylim という名前の引数で設定します. 引数として与えるのは,軸の両端の値(最小値と最大値)を指定する2つの値からなる ベクトルです.

要素を並べてベクトルを作るには, c という関数を使います.たった一文字ですが, これでも関数です.c の引数として渡したものをすべてまとめて, ひとつのベクトルを作ります.たとえば

num.array <- c(1, 3, 5, 7)         #  数値のベクトル
char.array <- c('aa', 'ab', 'bb')  #  文字列のベクトル
nc.array <- c(1, 3, 'bb')          # 文字列が含まれると,全部文字列だと解釈

のように使います.

グラフの x 軸を 0 から 100 の範囲に設定するには, c(0, 100) というベクトルを xlim に渡せばよいので,

plot(d$len, d$width,                             # みやすさのために適当に改行
     xlab = 'length (cm)', ylab = 'width (cm)',  # 軸ラベルの設定
     xlim = c(0, 100))                           # x軸の範囲の設定

のように書きます. なお,改行はただの空白と同じように無視されますので, 上の例のように適当に改行を入れて見やすくしましょう.

<練習>

maxという関数に数値のベクトルを渡すと,ベクトルの要素中 もっとも大きい値を返す.これを利用して,縦軸,横軸とも 0 から始まり, かつすべてのデータがグラフ内にプロットされる(はみ出す点がない)ように xlim と ylim を設定してグラフを描いてみる.


plot は「総称的」

plotは渡すオブジェクトの種類に応じて動作が違うことを 見てみましょう.

plot(d$len)

のように,数値が要素のベクトルを渡すと,何番めの要素かを横軸, その要素の値を縦軸にとったグラフが描けます.また,

plot(d)

のように,データフレームを丸ごと渡すと,そのすべての列の組み合わせについて 散布図を描いて,たてよこに並べた図ができあがります. 数値データでない d$sp が一方の変数となっている場合,その値が 'Sp1' か 'Sp2'かによってデータを分けて,それぞれの len や width の分布が プロットされています.

<練習>

ほかの人が書いたプログラムのなかで plotに渡している 引数の設定をそのまま自分のプログラムで利用しようとしても, そんな引数は設定できないと言われるかもしれません. 不思議な気がしますが,それは,与えているデータオブジェクトの種類が違うため, 呼び出されるのは別の関数で,受け付ける引数も違うためです.

plotの実体はいくつもの関数のあつまりだという ことを理解しておかないと,同じプログラムを書いたつもりなのに動作が違う, わけが分からない,ということになります.


hist() でヒストグラム

もうひとつ,高水準描画関数をためしてみます. ヒストグラムを描いてくれる histです. この関数に,数値がならんだベクトルをひとつ渡すと,適当な区画で区切った ヒストグラムが描けます (>グラフ).

histに渡すデータは,数値のベクトルである必要があります. 今の例では,d$sp は数値でないので,これを引数に指定してもグラフは描けません. また, データフレームの扱い方を説明したページ で,特定の列を指定するのに 書き方によって「指定した列ひとつだけからなるデータフレーム」を意味する場合と, 「指定した列に含まれる要素が並んだベクトル」を意味する場合があることを 説明しました.histはデータフレームは受け付けてくれませんので, 後者の指定方法をする必要があります.

<練習>

plotだのhistだの,ほんの一行の命令で あっさりグラフが描けてしまいましたね.さらにいろいろと細かい調整も したくなりますが,それは次のページで解説することにして, 描いたグラフをファイルに保存する方法を紹介します.

グラフを画像ファイルに記録する

画面に表示されたグラフを保存する

グラフを表示できたら,それをそのまま印刷することもできますが, ファイルに保存できれば,あとあといろいろな形で利用できます. R では,いろんな形式の画像ファイルを作ることができます. jpeg, png, bmpなどのビットマップ画像も, eps,PDF,ウインドウズメタファイルなどのベクトル画像も 用意されていますので,目的に応じて選びます.

ビットマップ画像とベクトル画像については,拙文 ウェブにのせる図の作り方 に簡単な説明がありますので,あわせてご覧ください.

画面にグラフを描いたあと,その画面がアクティブになった(一番おもてに出ている)状態で, [ファイル]メニューから保存したり,右クリック(Windowsの場合)で 表示されるメニューから保存したりできます.

<練習>

ちょっとお試しで書いたグラフを1枚とっておこう というならこれでじゅうぶです. ただ,プログラムでどんどんグラフを描いて画像ファイルに保存したいとなると, この方法は不向きです.


画像ファイルを作図デバイスに

予備知識3のところでも簡単に触れたように,入力画面で plot などの作図関数を呼ぶと, 画面にグラフが表示されますが,これは画面を作図デバイスとする デバイスドライバが自動的に起動して描いてくれたものです. 画面作図ドライバのかわりに,画像ファイルに書き込むデバイスドライバを起動すれば, グラフは画面に表示されずに画像ファイルに書き込まれます.

入力画面で help(device)と入力すると,使用可能な作図デバイスの種類が表示されます. また,R-Tips の 作図の準備 のところにR で使用可能なデバイスのリストがあります.

ファイルにグラフを書き込む作業は,

という手順で進めます. たとえば png という関数で png 形式対応の作図ドライバを 起動したあとグラフを描けば,png 形式の画像ファイルができあがります. 起動したデバイスは, dev.offという関数を呼んで閉じます. これをしないと画像ファイルがきちんとできません。 開けたら閉めることを忘れずに.

プログラムの実行中にエラーが起こって終わってしまったような場合、作りかけのファイルが 開きっぱなしで残ってしまうことがあります。そんなファイルは、削除しようにもアプリケーションが 使用中だからと断られてしまいます。そのような場合は、R のコンソールで dev.off() を直接実行してみてください。 開いている作図デバイスがなくなると、dev.off() を呼んでもエラーが返ってくるようになります。 そこまでやれば大丈夫。

さっそく実例.

png('test.png')        #  デバイスドライバの用意.最初の引数に作製するファイル名を与える
plot(d$len, d$width)   #  グラフを描く
dev.off()              #  デバイスを閉じる

画像ファイル用のデバイスを起動する関数(この例ではpng)では, 作製ファイル名のほか,いくつかの引数を渡すことができます. help(png) で確かめてみてください.

以下の例では,字を大きくして(pointsize = 18, デフォルトは12), 画像サイズは 400 x 400 ピクセル(デフォルトは 480 x 480) に指定しています.

png('test.png' , pointsize = 18, width = 400, height = 400)
plot(d$len, d$width)
dev.off()

なお,どの画像ファイルも特に大きさを指定しなければ適当な大きさのファイルが用意されます. 上の例のように大きさを指定する場合,ビットマップ画像の場合はピクセル数,ベクトル画像の場合は インチで width と height を指定します.


プログラムで画像ファイルを作る場合,まずは画面に表示させながらいろいろためして, これでよしとなったらファイル用のデバイスを起動して本番,という手順がよいでしょう. また,ここでは解説しませんが, 画面に作製した図をファイルにコピーする dev.copyという関数もあります.


関数にまとめる

ここまでの知識をもとに,ファイル名を受けとって,データファイルからデータを読み込み, グラフを画像ファイルに書き込むという関数を作ってみます.

# ファイルのベース名(拡張子の前の名前)を受けとり,
# ベース名に拡張子 .txt をつけた名前のデータファイルを読み込み,
# len と width の散布図を描いて png ファイルに記録する

len.width.scatter <- function(file.base.name)
{
    data.file <- paste(file.base.name, ".txt", sep = "")  # paste は文字列を連結する関数(既出)
    image.file <- paste(file.base.name, ".png", sep = "") # sep = "" を指定しないと空白が入る
    
    d <- read.table (data.file, header = TRUE)  # ファイルをデータファイルに読み込む
                                                #  ファイルが見つからないと,エラーとなって止る

    png(image.file)                          #  デバイスの用意
    plot(d$len, d$width)                     #  グラフを描く
    dev.off()                                #  デバイスを閉じる
}

このプログラムの意味するところは明らかですね. これをたとえば scatter1.R というファイルに保存して,source で 読み込んでから,

len.width.scatter ('len_text')

のようにして実行してみてください.

<練習>

つぎのページでは,さらに多彩なグラフを描く練習をします.とくに, 一枚の図にあとからいろいろ重ね描きしていく方法を説明します.


| Top Page | プログラミング | R 自動化 目次 | 索引 | 前へ | 次へ |