SAS

pictureフォーマットを軸に適用する場合の注意点

pictureフォーマットは数値の範囲を指定してその範囲の数値の表示形式を設定するフォーマットです。本ブログでは軸目盛からマイナス表示を取り除くときに使用していますが、pictureフォーマットの設定には注意する必要があります。

なおpictureフォーマットの設定については様々な方が紹介しておりますのでここでは取り上げません。以下のブログを参考にしてください。

デフォルトの状態でpictureフォーマットを使用した場合

試しに以下のコードを実行してみます。バタフライチャートやmirrored histogramと同様にB群のresponseの値をマイナスに反転させておき、原点から棒グラフが上下に伸びる形に出力します。
軸目盛はマイナスの値になっていますが、体裁の都合上そうしているだけで本来は0以上の値です。pictureフォーマットを使って目盛からマイナス表示を取り除きます。


data test;
   cat="測定項目1"; cat2="A群"; response=0.254;output;
   cat="測定項目1";  cat2="B群"; response=-0.177;output;
run;

proc format;
   picture val
      low-high="9.9";
run;

proc template;
define statgraph bar;
begingraph;

layout overlay /
yaxisopts=(linearopts=(tickvalueformat=val. viewmin=-0.3 viewmax=0.3 tickvaluesequence=(start=-0.3 end=0.3 increment=0.1)));

   barchartparm category=cat response=response/
      group=cat2
      name="bar";
   discretelegend "bar";

endlayout;
endgraph;
end;
run;
proc sgrender data=test template=bar;
run;
実行結果

Y軸の目盛りはtickvaluesequenceオプションで0.1間隔に設定していますが、正しく表示されていません。

これはpictureフォーマットのオプションの指定が足りないために起こります。

tickvaluesequenceオプションで目盛りを生成するとどうやら丸め誤差が発生するらしく、例えば0.1は0.099999….になってしまうようです。pictureフォーマットはデフォルトの状態だと
指定した桁数以上の数値は切り捨てますので、意図した表示にならない場合があります。

上記の例の場合、-0.1と表示される箇所が0.0と表示されてしまっています。これはtickvaluesequenceオプションでは厳密には-0.1ではなく-0.0999999…..が目盛りとして指定されており、pictureフォーマットによって少数第2位以降の数値が切り捨てられてしまうことが原因のようです。

tickvaluesequenceの丸め誤差はおそらく仕様だと思います。これで問題になるということはないと思いますが、気になるのであればtickvaluelistで全ての目盛りを定義するほうが無難かも。

また多くの方が指摘されている通りpictureフォーマットは出力形式のデフォルトの文字列長が決まっており、これを超えると文字切れを起こします。
当然目盛りも文字切れを起こす可能性があるので注意が必要です。

オプションを追加した場合

上記の問題を回避するにはpictureフォーマットのオプションを追加する必要があります。
ぐらい敵にはdefaultオプションで文字切れしない十分な文字列長を指定し、roundオプションを追加します。roundオプションはフォーマット適用前に数値に丸めるオプションです。

厳密にいうとroundオプションはmultiplierオプションで指定された値を数値にかけた後の値を整数に丸めます。指定したpicureフォーマットの小数点以下の最後の桁数をnとすると、multiplierのデフォルト値は10nです。

例えば0.099999….となっている数値を”9.9″のフォーマットを適用する場合、multiplierオプションは10となります。(小数第1位までの表示なので101)
multiplierをかけた後の数値は0.99999….となり、roundオプションにより1となります。multiplierは10だったのでフォーマットの表示はその10分の1である0.1となり、意図した値になります。

結構回りくどい説明ですが、簡単に言えば、roundオプションはフォーマットを適用する前に指定した小数桁になるように四捨五入するオプションと考えればよいでしょう。multiplierは設定をいじることはまずないでしょうし。

pictureフォーマットの作成時に以下のようにオプションを追加します。

proc format;
picture val(default=10 round)
low-high="9.9";
run;

修正後に実行すると以下のようになります。

修正後
修正後

軸目盛が意図した形で表示されました。