初級コマンド編 レコード間計算1(xtshare)

本章と次章では、レコード間の計算を実現するコマンドを二つ紹介する。
xtshareコマンドは、あるキー項目の値が同じ行について、ある数値項目の合計に対する各行の数値項目値の割合(シェア)を計算する。
ここでは、先に作成したスクリプトxtcut.shを再利用することにする。FDで、前章でおこなった手順で、xtcut.shをxtshare.shの名前でコピーしておこう。

新しくコピーされたファイル"xtshare.sh"を編集する。
xtcutで日付、数量、金額を抜き出したあと、日別の数量金額合計をxtaggコマンドで求める。そのデータに対してxtshareコマンドを適用し、各日付の数量、金額合計が、全体合計に占めるシェアを求める。xtshareでは"-k"でどの項目を単位にシェアを計算するかを指定し、"-f"にどの数値項目のシェアを求めるかを指定する。ここでは全体の金額合計に対する日々の金額合計のシェアであるので、"-k"の指定は必要なく「xtshare -f 数量,金額」でよい。ただし、xtshareコマンドは指定した数値項目についてのシェアを計算し、その値を新しい項目として指定するため、その新項目名を"-f"で指定した項目名の後に指定する必要がある。そこで「xtshare -f 数量:数量シェア,金額:金額シェア」と指定すればよい。
最後に、出力ファイル名(xtshare.xt)、およびコメントの変更も忘れずに。
これらの変更を反映させたスクリプトを下図に示しておく。

#/bin/bash
#===============================================================
# MUSASHI bash script
#===============================================================

#---- タイトル
title="チュートリアル"

#---- コメント
comment="xtshare"

#---- 各種変数(適宜修正すること)
inPath="/mnt/h00/prm/tutorial"

#---------------------------------------------------------------
# コマンド
#---------------------------------------------------------------
xtcut -f 日付,数量,金額 -i $inPath/dat.xt.gz |
xtagg -k 日付 -f 数量,金額 -c sum |
xtshare -f 数量:数量シェア,金額:金額シェア |
xtheader -l "$title" -c "$comment" -o xtshare.xt
#===============================================================

ここで指定した三行の意味は次の通りである。
xtcutで「日付」、「数量」、「金額」の項目を選択し、その結果をパイプラインで次のxtaggコマンドに送る。xtaggコマンドでは、日付を単位に、数量、金額を合計する。そしてその結果データは再びパイプラインによって次のxtshareコマンドに送られる。xtshare コマンドでは、全体に対する各日付のシェアを計算し、新しい項目「数量シェア」、「金額シェア」として出力する。その結果データはxtheaderコマンドに送られ、タイトルとコメントを変更し、その結果を"xtshare.xt"というファイルに書き込む。

スクリプトの編集が終れば保存して、実行する。結果データを確認すると下図のように、日別に数量シェアと金額シェアが計算されているはずである。

<?xml version="1.0" encoding="euc-jp"?>
<xmltbl version="1.00">
<header>
<title>
チュートリアル
</title>
<comment>
xtshare
</comment>
<field no="1">
<name>日付</name>
<sort priority="1">
</sort>
</field>
<field no="2">
<name>数量</name>
</field>
<field no="3">
<name>金額</name>
</field>
<field no="4">
<name>数量シェア</name>
</field>
<field no="5">
<name>金額シェア</name>
</field>
</header>
<body><![CDATA[
19960105 330 170023 0.023955 0.025761
19960106 376 202936 0.027294 0.030747
19960107 345 186710 0.025044 0.028289
19960108 365 192866 0.026495 0.029222
19960109 515 241954 0.037384 0.036659
19960110 487 213515 0.035351 0.03235
19960111 464 220741 0.033682 0.033445
19960112 642 315335 0.046603 0.047777
19960113 632 286111 0.045877 0.043349
19960114 325 170098 0.023592 0.025772
19960115 404 207313 0.029326 0.03141
19960116 626 322327 0.045441 0.048837
19960117 536 268251 0.038908 0.040643
19960118 502 248289 0.03644 0.037619
19960119 542 235548 0.039344 0.035688
19960120 576 250142 0.041812 0.0379
19960121 456 212493 0.033101 0.032195
19960122 375 175588 0.027221 0.026604
19960123 590 268325 0.042828 0.040655
19960124 524 215801 0.038037 0.032697
19960125 743 330867 0.053934 0.05013
19960126 643 276340 0.046675 0.041869
19960127 699 312099 0.05074 0.047287
19960128 419 231647 0.030415 0.035097
19960129 503 232898 0.036513 0.035287
19960130 562 260900 0.040796 0.03953
19960131 595 351001 0.043191 0.053181
]]></body>
</xmltbl>

次に、各効能2(大分類)別に日別シェアを求めて見よう。利用する項目として、前述の「日付」、「数量」、「金額」に加えて「効能2」の項目が必要となる。xtcutコマンドで追加する。
そして効能2別に求めるので、xtshareの"-k"に効能2を指定する。これらの変更を加えたスクリプトを以下に示しておく。結果は各自で確認してもらいたい。

#/bin/bash
#===============================================================
# MUSASHI bash script
#===============================================================

#---- タイトル
title="チュートリアル"

#---- コメント
comment="xtshare"

#---- 各種変数(適宜修正すること)
inPath="/mnt/h00/prm/tutorial"

#---------------------------------------------------------------
# コマンド
#---------------------------------------------------------------
xtcut -f 効能2,日付,数量,金額 -i $inPath/dat.xt.gz |
xtagg -k 効能2,日付 -f 数量,金額 -c sum |
xtshare -k 効能2 -f 数量:数量シェア,金額:金額シェア |
xtheader -l "$title" -c "$comment" -o xtshare.xt
#===============================================================

OnePoint NULL値
 結果を見れば分かるが、効能2や金額シェアの値が「*」になっている行があるであろう。これはNULL値のことである。効能2にNULL値が生じる原因としては、何らかの理由で効能2で分類されていない商品が存在することがあげられる。また金額シェアでのNULL値は、シェア計算をする際に利用した数値データに一つでもNULL値があれば、シェア計算結果もNULL値になるというルールがあるために発生する。MUSASHIでは全コマンドにおいて、「NULL値を含んだ計算結果はNULL値となる」。また計算不能(0割り算や数値の最大値を超えるなど)もやはりNULL値として扱われる。またレコード選択系のコマンド(xtsel, xtselstrなど)におけるNULLの扱いは、「指定された条件に含まれる項目の少なくとも一つがNULLであった場合は、その行を無視する(選択しない)」。NULLを扱うコマンドにはxtdelnul, xtnultoの二つあり、事前にNULL値に対して前処理を行うことができる。

OnePoint 途中結果の確認
スクリプトで用いるコマンドが本章の例のように増えてくると、各コマンドが出力する途中の結果を見たくなるケースもでてくる。例えば、最終結果のデータが思い通りのものになっていない場合には、それまでの途中経過を見ることは重要な作業である。その時に便利なコマンドとしてUNIXのオリジナルコマンド「tee」がある。出力結果を見たいコマンドの後にパイプで続けて「tee ファイル名」を挿入すると、その時点での途中経過が、指定したファイル名に保存される。もちろん「tee」の末尾にパイプを入れなければならない。このコマンドは、パイプから受け取ったデータを指定のファイルに書き出し、かつ次のパイプに送り込むという機能をもっている。本章で作成したスクリプトに「tee」を入れて、動作を確認してみよう。

練習課題

次のようなデータを作成しよう。