紅孔雀 このページをアンテナに追加 RSSフィード

2012-01-16

[] R でコマンドライン引数を取得する方法

R のスクリプトを作成するときに「集計対象のデータファイルはコマンドライン引数で指定したい」という場合があります。

それを実現するには、R コマンドの --args オプションを使用します。--args オプション以降は R コマンド自体のオプションとはみなされなくなります。

R --file=summary.r --args data.csv

そして、--args で渡された引数は commandArgs() 関数で取得することができます。

commandArgs(trailingOnly=TRUE)[1] # => "data.csv"

ポイントは trailingOnly=TRUE を指定することです。trailingOnly=TRUE を指定しない場合は、以下のように --args より前に指定したオプションを取得してしまいます。指定したオプションの数によって添え字がずれるため、例えば commandArgs()[3] と書いた場合に取得できる値は、R コマンドのオプションを書いた順番に依存します。

commandArgs()[1] # => "/usr/lib/R/bin/exec/R"
commandArgs()[2] # => "--file=summary.r"
commandArgs()[3] # => "--args"
commandArgs()[4] # => "data.csv"

[] R の read.csv で欠損値を NA に変換しながらデータを取り込む方法

以下の成績データ(data.csv)があるとします。データ中の「XX」及び「-1」は欠損値を表します。

名前,国語,算数,理科,社会
太郎,95,70,75,80
次郎,90,80,80,85
花子,80,90,80,70
A子,XX,70,70,70
B子,70,70,70,70
C子,80,80,80,80
D子,80,-1,80,80
E子,90,90,90,90
F子,90,XX,90,-1

ファイルを読み込むときに欠損値を NA に置き換えたい場合は、以下のように na.strings で NA に変換したい値を指定します。

read.csv("data.csv", header=TRUE, na.strings=c("XX",-1))

結果は以下の通りです。

  名前 国語 算数 理科 社会
1 太郎   95   70   75   80
2 次郎   90   80   80   85
3 花子   80   90   80   70
4 A子   NA   70   70   70
5 B子   70   70   70   70
6 C子   80   80   80   80
7 D子   80   NA   80   80
8 E子   90   90   90   90
9 F子   90   NA   90   NA

[] R で欠損値を除外して集計する

以下の成績データ(data.csv)があるとします。

名前,国語,算数,理科,社会
太郎,95,70,75,80
次郎,90,80,80,85
花子,80,90,80,70
A子,XX,70,70,70
B子,70,70,70,70
C子,80,80,80,80
D子,80,-1,80,80
E子,90,90,90,90
F子,90,XX,90,-1

各教科の平均点を求めるために以下の R スクリプトを実行すると、データに NA が含まれるため、思い通りの結果は得られません。

data <- read.csv("data.csv", header=TRUE, na.strings=c("XX",-1))

cat("国語平均:", mean(data["国語"]), "\n")
cat("算数平均:", mean(data["算数"]), "\n")
cat("理科平均:", mean(data["理科"]), "\n")
cat("社会平均:", mean(data["社会"]), "\n")

結果は以下の通りです。

国語平均: NA
算数平均: NA
理科平均: 79.44444
社会平均: NA

NA を除外して集計するには、na.rm=TRUE を指定します(他の関数でも使用可能です)。

data <- read.csv("data.csv", header=TRUE, na.strings=c("XX",-1))

cat("国語平均:", mean(data["国語"], na.rm=TRUE), "\n")
cat("算数平均:", mean(data["算数"], na.rm=TRUE), "\n")
cat("理科平均:", mean(data["理科"], na.rm=TRUE), "\n")
cat("社会平均:", mean(data["社会"], na.rm=TRUE), "\n")

結果は以下の通りです。

国語平均: 84.375
算数平均: 78.57143
理科平均: 79.44444
社会平均: 78.125

上記の例では列ごと(国語、算数、理科、社会)に見て NA を除外した上で平均を取る、という処理を行っていますが、行ごとにみて NA を含む行を集計対象外としたい場合もあります。その場合は na.omit() 関数で NA を含む行を削除することができます。

data <- read.csv(file, header=TRUE, na.strings=c("XX",-1))
na.omit(data)

結果は以下の通りです。

  名前 国語 算数 理科 社会
1 太郎   95   70   75   80
2 次郎   90   80   80   85
3 花子   80   90   80   70
5 B子   70   70   70   70
6 C子   80   80   80   80
8 E子   90   90   90   90

各集計関数のオプションで na.rm=TRUE を指定するのか、それとも na.omit() 関数を使用するのかはケースバイケースです。全教科の得点が分かっている人のみ集計したい場合は na.omit() を使う、教科ごとの平均点が分かれば良いという場合は na.rm=TRUE を指定する、という具合に用途に応じて使い分けます。