▼タブ展開

Der & Everitt (2001). Handbook of Statistical Analyses Using SAS, Second Edition. を眺めていたら infile ステートメントに expandtabs オプションを使っているのを見た.これまで一度も使ったことのないオプションである(きっと新しいオプションである).何だろう,と思ってマニュアルを確認したら,タブ区切りファイル(これを tsv形式と呼ぼう)を読むためのオプションである.なるほど.こういうオプションの使い方を若いSASユーザーが目の前でやって見せたりすると嫉妬するものだが,Everitt がやるとは(Derかな?).

私はこれまでどうしていたかというと,dlm オプションで十六進数の "09"x を指定していたのである.tsv形式のテキストファイルを読むことは多い.csv形式も多いのだが,EXCELファイルをテキスト出力する時のデフォルトがtsv形式のせいかも知れない.あまりにしばしばtsv形式を扱うので,タブコードが"09"xであることも覚えてしまったが,面倒だと思っていた.

infile in dlm = "09"x ;

と書くところを,

infile in expandtabs ;

と書くだけなのに,なぜこのオプションが便利なのか.それは人間にとって便利なのである.抽象度が高いほうが発達した言語なのである.そして何より美しい.(言語の美は,叙事詩から抒情詩へ,そして象徴詩へと昇っていった).
expandtabs オプションの内部動作は dlm = "09"x と同じことで,その動作に expandtabs という別名を付けただけにも見える.(実は,そうではなくて,expandtabs は dlm と同時に指定できるのである.しかも tsv形式ファイルでなくとも expandtabs を指定しても構わない).

我々は「タブのコードは何だっけ?」と躓くが,「tsv形式だからタブ展開のために expandtabs オプションをつけよう」という具合に躓かずに書ける."09"xは自然に浮かばないが,expandtabs は自然に浮かぶ.それは"09"xが機械言語に近く,expandtabs が自然言語に近いからである.

もっとも,expandtabs にも弱点がある.このオプションは文字通り,タブを展開するのである.つまりブランク8個におきかえるという動作をするようだ.従って欠損値がある場合,それを認識できない.ブランク文字に展開して,通常のリスト入力をするという動作をしているようなので,欠損値がブランクの場合は識別できないのである.欠損値がある場合は,CSVが良い.



▼床と天井

時々,SASの切捨関数の定義を混乱することがある.int 関数は明快だが,床と天井という floor 関数と ceil 関数の定義である.floor 関数はどの言語にもあるが,ceil 関数はSASに特有ではなかろうか?.なぜなら floor 関数さえあれば,ceil 関数は冗長だからである.しかし,あって邪魔ではない.一様乱数を整数化するときには ceil 関数を使えばきれにに書ける.たとえば区間 (1,300)の整数一様乱数を作るときに,多くの言語が持っている floor 関数を使うと,

ran = floor( ranuni( seed ) * 300 ) + 1 ;

と書く.しかし,ceil 関数があれば,

ran = ceil( ranuni( seed ) * 300 ) ;

と書ける. +1 を書かなくてもいい,というだけであるが・・・.

intは単なる切捨関数で整数部分を返す.floorとceilは床と天井の整数を返すのである.
int と floor は正の領域では等しい結果を返すが,引数が負の場合は異なる値を返す.
int と ceil は負の領域では等しい結果を返すが,引数が正の場合は異なる値を返す.

floor()
引数以下(引数と同じか,引数より小さい)の最大整数を返す.引数の値と最近隣整数値との差の絶対値が10-12以内の場合,それは整数であると見なされ(つまり10-12以下は0であると扱われ)その整数の値を返す.

ceil()
引数以上(引数と同じか,引数より大きい)の最小整数を返す.引数の値と最近隣整数値との差の絶対値が10-12以内の場合,それは整数であると見なされ(つまり10-12以下は0であると扱われ)その整数の値を返す.

文字通り,床と天井の図を書くと明白になる.床と天井という関数名は実にうまい,センスがいい.

3



2  (天井)

| ←−−−−引数

1  (床)



0



-1


引数 floor() ceil()
3 3 3
2.1 2 3
-1.6 -2 -1
-2.4 -3 -2
-1-1.e-11 -2 -1
1-1.e-11 0 1
1+1.e-11 1 2
-1-1.e-12 -2 -1
-1+1.e-12 -1 -1
1-1.e-12 1 1
1+1.e-12 1 2
-1-1.e-13 -1 -1
1-1.e-13 1 1
1+1.e-13 1 1


10-12以下の差異は無視される(または0とみなされる)ことになっている.10-12より小さな,10-13では確かに差異は無視されている.また,10-12より大きな,10-11では確かに加算と減算が機能している.

floor の引数が「 -1 - 1.e-12 」の時,およびceilの引数が「 1 + 1.e-12 」の時には,それぞれれ「-1 より小さい」,「1 より大きい」と判定された値が返っている.