2010/11/1(2012/11/8 一 部 改 訂 ) SAS 講 習 会 用 テキスト(Base SAS 編 ) 目 標 SAS 言 語 を 用 いたデータ 入 力 加 工 集 計 レポート 作 成 を 行 うプログラミングの 基 礎 を 習 得 します 内 容 1. SAS 概 要... 2 1.1 SAS の 基 本 的 概 念 文 法 制 限 データライブラリと 使 い 方 ~ DATA ステッ プと PROC ステップ 命 名 規 則 LIBNAME ステートメント 関 数 演 算 子 欠 損 値 エラー 対 応... 2 1.2 データ 読 取 り 変 数 作 成 と 横 方 向 の 集 計 処 理 ~ FILENAME LIBNAME INPUT SET IMPORT EXPORT 割 り 当 てステートメント 集 計 関 数 データセットオプシ ョン PRINT SORT プロシジャ... 16 2. データ 加 工... 36 2.1 フ ァイルの 連 結 マージ 更 新 を 含 む プログラミングステートメント ~ SET,MERGE,UPDATE ステートメント,DO ループ, 配 列 処 理... 36 2.2 日 付 処 理 関 数 フォーマットの 利 用 と DATA ステップを 用 いたレポーティング ~ 日 付 フォーマット 日 付 インフォーマット 日 付 関 数 FORMAT プロシジャ BY グループ 処 理 PUT ステートメント... 55 3. レポーティング... 69 3.1 集 計 デ ー タ セ ッ ト の 転 値 SQ L プ ロ シ ジ ャ ~ FREQ SUMMARY TRANSPOSE SQL プロシジャ... 69 3.2 レポーティングとマクロ 処 理 ~ TABULATE プロシジャとマクロ 処 理... 89 [ 別 表 1] DATA ステップで 使 えるステートメント 一 覧... 106 [ 別 表 2] PROC ステップの 種 類... 107 [ 別 表 3] グローバルステートメント 一 覧... 107 [ 別 表 4] 演 算 子 一 覧... 108 [ 別 表 5] 関 数 一 覧... 108 [ 別 表 6] フォーマット 一 覧... 112 [ 別 表 7] インフォーマット 一 覧... 119 [ 別 表 8] merge ステートメントによる 2 つのデータセットのマージ 例... 122 1
1. SAS 概要 1 SAS 言語 は PL/1,C,Fortran,BASIC などと同じようにプログラミング言語の一種です ただし 元々は コンピュータ専門家ではない統計解析専門家のために開発されたデータ入力 加工 解析用の言語です そのため PL/1,C などの手続き型言語と比較すると はるかに使いやすい仕様となっています SAS 言 語は主にデータ加工を柔軟に行う目的を実現するために豊富な関数やプログラミング機能を有する DATA 2 ステップ と 特定のデータ分析 集計 レポートを行うために用意されているパラメータ指定仕様の 3 PROC ステップ の 2 つの性格の異なるコンポーネントを有しており これらを組合せてプログラミング を行うようになっています 1.1 SAS の基本的概念 文法 制限 データライブラリと使い方 DATA ステップと PROC ステップ 命名規則 LIBNAME ステートメント 関 数 演算子 欠損値 エラー対応 SAS の操作方法 基本的概念および SAS 言語の要素などについて学びます [SAS の起動と終了] まず SAS を起動します デスクトップに SAS 起動アイコンがある場合は それをダブルクリックしま す 無ければ Window から SAS 起動プログラム選択します SAS の最新バージョンは 9.2 ですがここでは 9.1 を用いています このテキストの範囲ではいずれのバー ジョンでもほとんど同じです 起動すると 以下のようにいくつかの画面(window)が表示されます 1 SAS は 1973 年ごろから開発がはじまり 当時は第四世代言語と呼ばれていました 2 使いやすいだけでなく 扱えるデータ量やファイル形式などに制約が無く また 複雑な処理も高級言語なみに実行できる機能を持っています なお DATA ステップはコンパイル言語です 3 PROC ステップの個々の構成要素をプロシジャと呼んでいます これは DLL(動的結合ライブラリ)ファイルとなっています 2
コマンドバー メニューバー ツールバー エディタ 画 面 アウトプット 画 面 エクスプローラ 画 面 ログ 画 面 メッセージ 表 示 領 域 現 在 の 作 業 フォルダ SAS にはたくさんの 画 面 (WINDOW)がありますが ユーザが 良 く 使 う 主 な 画 面 は 上 記 の 図 の 中 央 の 上 部 に 表 示 されている エディタ 画 面 ( プログラム 編 集 画 面 ) 中 央 下 部 に 表 示 されている ログ 画 面 そして 右 側 に 表 示 されている アウトプット 画 面 ( リスト 出 力 画 面 )の 3 画 面 です ユーザはエディタ 画 面 の 中 に 処 理 したい 内 容 を SAS 言 語 で 書 いたプログラムとしてコーディングを 行 い サブミットしたい 範 囲 を 選 択 状 態 にしてからツールバーのサブミットアイコン( 人 が 走 っている 形 のアイ コン)をクリックします 次 に プログラムにエラーがなかったかどうか 読 込 みや 書 き 込 みを 行 ったデ ータセットの 情 報 とか 実 行 時 間 などの 情 報 をログ 画 面 で 確 認 し 統 計 計 算 などの 処 理 結 果 を 表 示 するプロ グラムの 場 合 は アウトプット 画 面 または 他 の 出 力 画 面 ( 例 えば HTML 出 力 画 面 やグラフ 表 示 画 面 )に 思 った 通 りの 実 行 結 果 が 出 力 されていいるかどうかを 確 認 します 途 中 で 作 成 中 または 完 成 したプログラ ムをファイルに 保 存 しておきます このような 操 作 を 繰 り 返 してデータ 処 理 プログラムを 完 成 させていき ます 左 側 の 画 面 は 右 側 の 表 示 エリアと 区 別 された 領 域 となっており このときはドッキングした 状 態 になって います 下 の 方 にあるタブをクリックすることにより エクスプローラ (SAS エクスプローラ)と 結 果 画 面 を 切 り 替 えて 表 示 できる 画 面 です エクスプローラ 画 面 は SAS ファイルを 検 索 する ライブラリ を 良 く 使 うことになります 結 果 画 面 は リスト 出 力 結 果 やグラフ 出 力 結 果 を 個 々のアイテムとしてアイコン 表 示 してあり 実 行 済 みで 保 持 されて いる 結 果 アイテムをすばやく 検 索 するときに 使 います メニューバー には ファイル 編 集 表 示 ツール ソリューション ウィンドウ ヘ ルプ の7つのメニューが 並 んでいます これらはプルダウンメニューになっており この 中 に 含 まれて... いるコマンド 群 は SAS 以 外 の 他 のウィンドウアプリケーションと 大 体 同 じくくり になっています 3
メニューバーから 良 く 使 うコマンドは 以 下 のとおりです エディタ をアクティブにした 上 で ファイル メニューから プログラムの 新 規 作 成 プログラ ムを 開 く 上 書 き 保 存 名 前 を 付 けて 保 存 のサブメニューを 選 択 します. 対 象 画 面 をアクティブにしておいて 編 集 メニューから すべて 選 択 した 後 コピー また 元 に 戻 す やり 直 し の 操 作 そして 検 索 置 換 などの 操 作 を 行 います. 表 示 メニューから 拡 張 エディタ を 選 択 して 新 しいエディタ 画 面 を 開 く. また 閉 じてしまった ログ アウトプット 結 果 エクスプローラ などの 画 面 を 再 度 表 示 します. ツール メニューから テキストエディタ を 開 く(ただしこれは 上 記 表 示 メニューから 拡 張 エディタ を 選 択 して 新 しいエディタ 画 面 を 開 くと 同 じです) ツール メニューから ユーザ 設 定 や オプション を 選 択 し 設 定 を 確 認 したり 変 更 します.. メニューバーの 下 にはユーザが 直 接 コマンドを 入 力 する コマンドバー と ツールバー があります コマンドバーはメニューバーにあるコマンドをメニュー 選 択 ではなく 直 接 コマンドとして 入 力 できる 機 能 です 例 えば log とタイプして 左 のチェックマークを 押 すかエンターキーを 押 すと ログ 画 面 がアクティ ブになります ツールバーにはメニューバーにあるコマンドの 中 で サブミット や コピー ペース ト など 良 く 使 うコマンドをアイコンとして 格 納 しています 画 面 の 下 にはコマンドを 実 行 したときに SAS から 出 るメッセージを 表 示 する 領 域 と 現 行 の 作 業 フォル ダのディレクトリパスを 表 示 するエリアがあります 現 行 の 作 業 フォルダは 重 要 になる 場 合 があります 例 えば 作 成 中 の SAS プログラムを 保 存 するのに コマンドバーから file "temp.sas" とファイルのパス を 指 定 せずに 名 前 だけをタイプしてエンターを 押 したり SAS プログラムの 中 で file "temp.txt"; などと ファイルをフルパス 指 定 せずにサブミットした 場 合 SAS はこの 現 行 の 作 業 フォルダをカレントディレ クトリとみなし このフォルダの 中 にファイルを 作 成 します というわけでどこに 作 成 されたかを 知 るた めに 重 要 というわけです なお ここでいう 作 業 フォルダは 後 述 する 一 時 SAS データセットを 格 納 する WORK ライブラリの 所 在 とは 全 く 異 なる 点 に 注 意 してください (WORK ライブラリの 所 在 は libname コ マンドでわかります) SAS セッションを 終 了 するには ファイル メニューから 終 了 を 選 択 します SAS セッションを 終 了 しますか? と 聞 いてきますので OK を 選 択 すると SAS は 終 了 します 右 上 の X のところをクリ ックしても 同 じです では SAS を 終 了 しないでそのままで 続 けます [DATA ステップと PROC ステップ] SAS 言 語 によるプログラミングは DATA ステップと 呼 ばれる 実 行 単 位 と PROC ステップと 呼 ばれる 実 行 単 位 を 組 合 せて 行 います DATA ステップはデータ 検 索 加 工 機 能 を 実 行 するためのプログラミング 言 語 部 分 であり PROC ステップは 基 本 統 計 やレポーティングその 他 の 特 定 機 能 を 実 行 するために 用 意 され ている 組 み 込 みモジュールです DATA ステップは DATA ステートメントで 始 まり PROC ステップは PROC ステートメントで 始 まり どちらも RUN ステートメントで 明 示 的 に 終 了 します ただし RUN ステートメントを 記 述 しなくても 次 の DATA ステップまたは PROC ステップを 開 始 すればその 前 の DATA ステップまたは PROC ステップは 暗 黙 的 に 終 了 します なお DATA ステップと PROC ステップ に 属 しない 汎 用 ステートメントもあります では SAS の 使 い 方 を 実 習 するために プログラミングを 体 験 してみましょう 以 下 のプログラムをエデ ィタに 入 力 してください 入 力 が 終 わったらサブミットしてください なお /* */ で 囲 んだテキスト 部 分 4
はコメントですので 入 力 しなくても 結 構 です (プログラム 1.1-1) options nocenter; /*オプション 文 */ /* 汎 用 ステートメント*/ data hello; /*データ 文 */ /*DATAステップの 開 始 */ message="hello, World"; /* 割 り 当 て 文 */ /*DATAステップで 使 えるステートメント*/ /*ラン 文 */ /*DATAステップの 終 了 */ proc print; /*プロックプリント 文 */ /*PROCステップの 開 始 */ (ログ) 1 options nocenter; /*オプション 文 */ /* 汎 用 ステートメント*/ 2 data hello; /*データ 文 */ /*DATA ステップの 開 始 */ 3 message="hello, World"; /* 割 り 当 て 文 */ /*DATA ステップで 使 えるステートメント*/ 4 NOTE: データセット WORK.HELLO は 1 オブザベーション 1 変 数 です NOTE: DATA ステートメント 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.22 秒 CPU 時 間 0.03 秒 4! /*ラン 文 */ /*DATA ステップの 終 了 */ 5 proc print; /*プロックプリント 文 */ /*PROC ステップの 開 始 */ 6 NOTE: データセット WORK.HELLO から 1 オブザベーションを 読 み 込 みました NOTE: PROCEDURE PRINT 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.82 秒 CPU 時 間 0.32 秒 OBS message 1 Hello, World ログにエラーが 出 た 場 合 や 出 力 結 果 が 出 ない 場 合 は プログラムにタイプミスがありますので 訂 正 して 再 度 サブミットしてください ここではとにかく 上 手 く 結 果 が 出 るまでやってください [プログラムの 保 存 ] 上 手 く 動 いたプログラムはファイルに 保 存 しておきましょう プログラム 編 集 画 面 をアクティブにしてお いてから メニューバーの ファイル から 名 前 を 付 けて 保 存 を 選 択 して プログラム 名 をつけて 保 存 します 以 降 ときどき 名 前 を 変 えて 保 存 しておくと 良 いと 思 います 保 存 先 の 標 準 フォルダ 名 は c: USERS ユーザ 名 DOCUMNETS MY SAS Files 9.1 4 です 4 ここは 標 準 の SASUSER ディレクトリにもなっています 5
まずエディタウィ ンドウの 枠 をクリ ックしてをアクテ ィブにします. 保 存 先 の 標 準 フォ ルダ 名 はユーザド キュメントの 下 の MY SAS Files\9.1 です.ま ず 確 認 し て 変 更 したけれ ば 変 更 します. 保 存 したプログラムをエディタによびだすにはファイルメニューのプログラムを 開 くから 保 存 したファイ ルを 選 択 します または Window の Explore から 呼 び 出 したい SAS プログラムファイルをエディタ 画 面 に Drag&Drop しても 同 じ 結 果 になります 開 いたプログラムファイルの 名 前 の 付 いたエディタが 新 たに オープンします [SAS データセット] SAS で 管 理 するデータセットを SAS データセットと 呼 びます SAS データセットは EXCEL と 同 じよう な 表 形 式 のデータ 集 合 の 形 をしており 行 (レコード) 方 向 をオブザベーション 列 (カラム) 方 向 を 変 数 と 呼 びます 5 EXCEL には 行 や 列 の 数 に 制 限 がありますが SAS には 制 限 がありません 6 SAS デ ータセットの 特 徴 は データ 部 と 呼 ばれるデータ 部 分 に 加 えて ディスクリプタ 部 と 呼 ばれるデータセッ トの 記 述 部 分 が 備 わっていることです ディスクリプタ 部 にはデータセット 全 体 に 関 する 情 報 (インデク ス 情 報 など)や 各 変 数 情 報 ( 型 長 さ ラベル フォーマットなど)が 格 納 されています これ 以 降 プログラムを 入 力 してサブミットするときは 必 ず 実 行 したい 部 分 を 選 択 ( 反 転 状 態 )してか らサブミットしてください 5 オブザベーション 変 数 という 呼 び 名 は SAS 言 語 が 元 々 統 計 解 析 用 のアプリケーション 開 発 言 語 として 開 発 された 歴 史 に 由 来 しています 6 OS の 制 限 (SAS8.2 以 前 では 変 数 の 数 の 上 限 は 32767 でしたが SAS9.1 からそれ 以 上 オブザベーションは 容 量 の 制 約 ) 内 になります 6
(プログラム 1.1-2) data sample; /*データセットの 作 成 */ input ID name $ sex $ age height weight; /* 変 数 の 名 前 と 型 を 決 めて 読 み 込 みを 実 行 する 文 */ cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001 fujita M 30 175 70 002 suzuki F 29 168 59 003 takahashi M 32 180 85 004 tanaka M 40 178 77 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ (ログ) 7 data sample; /*データセットの 作 成 */ 8 input ID name $ sex $ age height weight; /* 変 数 の 名 前 と 型 を 決 めて 読 み 込 みを 実 行 する 文 */ 9 cards; NOTE: データセット WORK.SAMPLE は 4 オブザベーション 6 変 数 です NOTE: DATA ステートメント 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.00 秒 CPU 時 間 0.00 秒 9! /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 14 ; /*データを CARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ 15 proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ 16 NOTE: データセット WORK.SAMPLE から 4 オブザベーションを 読 み 込 みました NOTE: PROCEDURE PRINT 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.03 秒 CPU 時 間 0.01 秒 OBS ID name sex age height weight 1 1 fujita M 30 175 70 2 2 suzuki F 29 168 59 3 3 takahash M 32 180 85 4 4 tanaka M 40 178 77 [DATA ステップのループ 実 行 の 仕 組 み] DATA ステップは 入 力 するオブザベーションが 無 ければ 1 回 だけ 実 行 されます しかし 外 部 データからの 入 力 (INPUT ステートメント)や SAS データセットからの 入 力 (SET ステートメントなど)があるときは 読 み 取 るデータ 行 (SAS データセットの 読 み 取 りの 場 合 はオブザベーション)が 尽 きるまで 自 動 的 に 繰 り 返 し 実 行 されます これを DATA ステップのループ 実 行 と 呼 びます そして SAS データセットに 書 きこみ を 行 うステートメントである OUTPUT ステートメントがその DATA ステップの 中 に 存 在 しなければ DATA ステップの 終 わり(RUN ステートメントもしくは CARDS ステートメント)の 直 前 に OUTPUT ステートメン トを 自 動 的 に 挿 入 し 読 み 込 むデータ 行 またはオブザベーションが 尽 きるまで DATA ステップで 作 成 する 各 変 数 値 の 値 (これをプログラムデータベクトルと 呼 んでいます )を 持 つ1オブザベーションを 作 成 する SAS データセットへの 書 き 込 みを 繰 り 返 し 実 行 します この 例 では 実 行 ステートメントは INPUT ステー トメントのみとなっており ここで 読 み 込 まれた 6 個 の 変 数 値 を 持 つオブザベーションをデータ 行 の 数 で ある 4 回 DATA ステップがループ 実 行 され 都 合 4 オブザベーションを 持 つ SAS データセット SAMPLE 7
が 作 成 されます [SAS データセットのディスクリプタ 部 の 表 示 ] (プログラム 1.1-3) proc contents data=sample; /*ディスクリプタ 部 を 表 示 するプロシジャ*/ (ログ) NOTE: PROCEDURE CONTENTS 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.06 秒 CPU 時 間 0.01 秒 CONTENTS プロシジャ 2010 年 09 月 27 日 月 曜 日 午 前 11 時 02 分 57 秒 9 データセット 名 WORK.SAMPLE オブザベーション 数 4 メンバータイプ DATA 変 数 の 数 6 エンジン V9 インデックス 数 0 作 成 日 時 2010 年 09 月 27 日 月 曜 日 午 後 02 時 42 分 20 秒 オブザベーションのバッファ 長 48 更 新 日 時 2010 年 09 月 27 日 月 曜 日 午 後 02 時 42 分 20 秒 削 除 済 みオブザベーション 数 0 保 護 圧 縮 済 み NO データセットタイプ ソート 済 み NO ラベル データ 表 現 WINDOWS_32 エンコード shift-jis Japanese (SJIS) エンジン/ホスト 関 連 情 報 データセットのページサイズ 4096 データセットのページ 数 1 データページの 先 頭 1 ページごとの 最 大 OBS 数 84 先 頭 ページの OBS 数 4 データセットの 修 復 数 0 ファイル 名 C:\Users\Hideo\AppData\Local\Temp\SAS Temporary Files\_TD7592\sample.sas7bdat 作 成 したリリース 9.0101M3 作 成 したホスト WIN_PRO 変 数 と 属 性 の 昇 順 リスト # 変 数 タイプ 長 さ 1 ID 数 値 8 4 age 数 値 8 5 height 数 値 8 2 name 文 字 8 3 sex 文 字 8 6 weight 数 値 8 [ 変 数 の 型 ] SAS の 変 数 のタイプ( 型 )は 以 下 のとおり 数 値 タイプと 文 字 タイプの 2 通 りしかありません 変 数 のタイプ 数 値 タイプ 8
内 部 的 に 3 バイト~8バイト 7 の 浮 動 小 数 点 形 式 で 格 納 される 文 字 タイプ 1~32767 バイトの 長 さまでの 文 字 列 を 値 として 持 つことができる 数 値 変 数 は 固 定 小 数 点 形 式 で 持 つことができませんので 丸 め 誤 差 にシビアなアプリケーションに SAS を 使 うような 場 合 は 注 意 が 必 要 です 文 字 変 数 に 定 数 を 与 えるには ダブルクオテーション(")で 囲 むか シングルクオテーション(')で 囲 んで 指 定 します 例 name= Robert Edison sex= M [SAS カタログ] SAS で 管 理 するファイルには SAS データセットの 他 にもグラフィック 情 報 フォーマット 定 義 情 報 を 保 存 したものなどがあります これらはそれぞれ SAS グラフィックカタログ SAS フォーマットカタログ などと 呼 び 合 わせて SAS カタログと 呼 びます SAS データセットと SAS カタログを 合 わせて SAS フ ァイルと 呼 びます (プログラム 1.1-4) proc format; /*ユーザ 定 義 フォーマットの 作 成 */ value $a "fujita"=" 藤 田 です " "tanaka"=" 田 中 です " other="その 他 です "; proc print data=sample; format name $a.; /* 変 数 name の 値 に 定 義 したフォーマット($a)を 適 用 して 表 示 */ (ログ) NOTE: 出 力 形 式 $A を 作 成 しました OBS ID name sex age height weight 1 1 藤 田 です M 30 175 70 2 2 その 他 です F 29 168 59 3 3 その 他 です M 32 180 85 4 4 田 中 です M 40 178 77 (プログラム 1.1-5) proc catalog cat=formats; /*SASカタログを 管 理 するプロシジャ*/ contents; /*カタログ 内 のフォーマット 定 義 名 を 確 認 */ カタログの 内 容 : WORK.FORMATS # 名 前 タイプ 作 成 日 更 新 日 説 明 -------------------------------------------------------------------------- 7 LENGTH ステートメントで 長 さを 定 義 しなかった 場 合 は8バイトに 設 定 されます 9
1 A FORMATC 27SEP2010:14:49:12 27SEP2010:14:49:12 [ 一 時 ライブラリと 永 久 ライブラリ libname ステートメント] SAS ファイルは SAS 起 動 時 に 自 動 的 に 割 り 当 てられた WORK と 呼 ばれるライブラリ 参 照 名 で 参 照 する 物 理 ディレクトリの 中 に 一 時 的 に 作 られ SAS 終 了 時 に 自 動 的 に 消 去 されます WORK という 名 前 以 外 のライブラリ 参 照 名 でユーザ 指 定 した 物 理 ディレクトリに 保 存 するよう 指 定 すると SAS 終 了 後 も 残 りま す このようにして 保 存 した SAS ファイルを 永 久 SAS データセットあるいは 永 久 SAS ファイルと 呼 び ます (プログラム 1.1-6) libname mydata "C:\temp"; /* 物 理 ディレクトリ C:\temp をライブラリ 参 照 名 mydata で 参 照 させる*/ data mydata.sample; /* 永 久 データセットの 作 成 */ input ID name $ sex $ age height weight; /* 変 数 の 名 前 と 型 を 決 めて 読 み 込 みを 実 行 する 文 */ cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001 fujita M 30 175 70 002 suzuki F 29 168 59 003 takahashi M 32 180 85 004 tanaka M 40 178 77 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=mydata.sample; /*データ 部 を 表 示 するプロシジャ*/ proc contents data=mydata.sample; /*ディスクリプタ 部 を 表 示 するプロシジャ*/ しかしながら SAS ユーザの 便 宜 にために SAS システムはセッション 開 始 時 にユーザドキュメント (c: USERS DOCUMENTS)の 下 の My SAS Files 9.1 フォルダを SASUSER というライブラリ 参 照 名 で 自 動 的 に 割 り 当 てています これを 利 用 すれば libname ステートメントを 実 行 しなくても 自 由 に SAS ファイルを 永 久 保 存 することができます (プログラム 1.1-7) data sasuser.sample; /*SASUSERライブラリに 永 久 データセットを 作 成 する*/ input ID name $ sex $ age height weight; /* 変 数 の 名 前 と 型 を 決 めて 読 み 込 みを 実 行 する 文 */ cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001 fujita M 30 175 70 002 suzuki F 29 168 59 003 takahashi M 32 180 85 004 tanaka M 40 178 77 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sasuser.sample; /*データ 部 を 表 示 するプロシジャ*/ proc contents data=sasuser.sample; /*ディスクリプタ 部 を 表 示 するプロシジャ*/ 10
[ 命 名 規 則 (SAS 名 の 規 則 )] SAS データセット 名 変 数 名 などつけ 方 には 基 本 的 に 以 下 の 規 則 が 適 用 されます データセット 名 変 数 名 の 命 名 規 則 長 さ 32 文 字 以 内 (すべて 半 角 ) 先 頭 の 1 文 字 はアルファベット(A~Z)もしくはアンダースコア(_)のいずれかでなければなりませ ん 2 文 字 目 以 降 はアルファベット(A~Z)もしくはアンダースコア(_)もしくは 数 字 (0~9)のいずれ かが 使 えます 名 前 の 中 に 漢 字 やブランクが 使 えないことに 注 意 してください 8 なお データセット 名 変 数 名 のアルファベットの 大 文 字 小 文 字 の 区 別 については 以 下 のように 取 り 扱 われます データセット 名 変 数 名 の 大 文 字 小 文 字 の 区 別 データセット 名 は 大 文 字 小 文 字 の 区 別 はなく すべて SAS 内 部 で 大 文 字 として 認 識 されます 変 数 名 は DATA ステップや PROC ステップのプログラミングレベルおよび 実 行 中 は 大 文 字 小 文 字 の 区 別 はなく 同 じ 文 字 として 認 識 されます ただし データセットに 格 納 する 変 数 名 や SAS からの 出 力 では 最 初 に 定 義 したとおりに 大 文 字 小 文 字 を 区 別 して 保 存 され 表 示 されます 9 基 本 的 には 同 じ 命 名 規 則 が 配 列 名 ステートメントに 置 くラベル 名 マクロ 定 義 名 マクロ 変 数 名 カタログ 名 ライブラリ 参 照 名 などにも 適 用 されます ただし ユーザー 定 義 フォーマット 名 では 文 字 フ ォーマット 名 は"$"で 始 まること またライブラリ 参 照 名 などは OS の 制 約 も 受 けるなど 若 干 異 なる 場 合 も ありますので 注 意 が 必 要 です 特 に C 言 語 など 大 文 字 小 文 字 を 区 別 するプログラミング 言 語 で 書 かれたプ ログラムを SAS 言 語 で 書 き 直 すような 場 合 は 注 意 が 必 要 です ( 問 題 ) SAS 名 (データセット 名 または 変 数 名 )として 有 効 か 無 効 かを 考 えて 自 分 で 確 認 してください A20101010 A2010/10/10 _2010_10_10 ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdef [ステートメント( 文 )] SAS 言 語 には 通 常 のプログラミング 言 語 と 同 じようにプログラミングステートメント( 文 )が 用 意 され ています 1 個 のステートメントは キーワード( 定 型 語 )で 始 まりセミコロン(;)で 終 了 します キ ーワードとセミコロン 以 外 にステートメントに 含 まれる 他 の 要 素 は 変 数 名 データセット 名 関 数 名 フォーマット 名 定 数 パラメータなどの 1 文 字 以 上 の 長 さを 持 つワード( 語 )と 演 算 子 記 号 およびブ ランク( 空 白 )などの 1 文 字 の 長 さの 特 殊 文 字 です ワードの 区 切 り 文 字 はブランク 1 個 以 上 です た だし 演 算 子 (+-*/など)や 記 号 ( やカッコや 引 用 符 など)も 通 常 ワード 間 の 区 切 り 文 字 として 認 識 され ます そのため これらの 特 殊 文 字 をワードとワードの 間 に 記 述 する 場 合 ブランクはあってもなくても かまいません また 1 つのステートメントを 複 数 行 にわたって 書 いても 1 つの 行 に 複 数 のステートメ ントを 書 いてもかまいません ただし ワードの 途 中 で 改 行 することは 許 されません なお キーワ ードを 含 むワードのアルファベットは 大 文 字 (A~Z) 小 文 字 (a~z)いずれで 書 いてもかまいません [ 別 表 1] に SAS の DATA ステップで 使 える 主 要 なステートメントの 一 覧 を 表 示 しましたので ざっと 見 てみましょう 8 変 数 名 には 256 文 字 までのラベルを 付 けることができ 漢 字 も 使 えます 9 CONTENTS プロシジャを 用 いて 変 数 名 をデータセット 出 力 するような 場 合 に 注 意 が 必 要 となります 11
[ 別 表 2] に SAS の Base プロダクトで 使 える 主 要 な PROC ステップの 一 覧 を 表 示 しましたので ざっと 見 てみましょう [ 別 表 3] に SAS の 主 要 なグローバルステートメントの 一 覧 を 表 示 しましたので ざっと 見 てみましょう [ 関 数 ] SAS は 豊 富 な 関 数 を 備 えています 統 計 関 数 や 分 布 関 数 や 乱 数 発 生 関 数 といったデータ 解 析 のための 関 数 は 勿 論 のこと 文 字 関 数 なども 充 実 しています [ 別 表 5] に 主 要 な 関 数 を 表 示 しましたので 見 てみましょう [ 演 算 子 ] [ 別 表 4] に SAS で 使 える 主 要 な 演 算 子 を 表 示 しましたので 見 てみましょう ちなみに SAS の 論 理 演 算 結 果 は 真 の 場 合 は 値 1 を 返 し 偽 の 場 合 は 値 0 を 返 します (プログラム 1.1-8) data _null_; set sample; check=(height>=170); put height= check=; (ログ) height=175 check=1 height=168 check=0 height=180 check=1 height=178 check=1 /*データセットを 作 らないでDATAステップを 開 始 する*/ /*SASデータセットsampleを 読 み 込 む*/ /*height>=170の 真 偽 値 を 変 数 checkに 格 納 する*/ /* 変 数 height 値 とcheck 値 をログに 書 き 出 す*/ [ 欠 損 値 ] SAS 言 語 では 数 値 タイプ 変 数 の 欠 損 値 はピリオド 1 個 (.)で 与 えます また 標 準 的 な 表 示 も 同 じです ま た._および.A~.Z までの 27 個 の 特 殊 欠 損 値 を 通 常 の 欠 損 値 と 区 別 して 持 たせることが 可 能 です 10 一 方 文 字 タイプ 変 数 の 欠 損 値 はヌル 値 ""またはブランク 1 個 " "で 与 えます 新 たに 定 義 する 文 字 変 数 の 場 合 はどちらも 長 さ 1 のブランクの 値 として SAS データセットに 格 納 され 既 に 存 在 する 文 字 変 数 の 場 合 は 定 義 された 長 さのブランク 文 字 列 を 値 として SAS データセットに 格 納 されます 文 字 タイプ 変 数 の 欠 損 値 には 特 殊 欠 損 値 はありません また 長 い 方 の 長 さに 足 りない 方 の 文 字 列 はブランクを 埋 めてから 比 較 されますので 長 さの 異 なる 文 字 タイプ 欠 損 値 の 比 較 結 果 は 等 しくなります 欠 損 値 は 統 計 量 を 計 算 する 上 での 有 効 な 値 としてカウントせず 別 途 取 り 扱 われます 文 字 タイプの 欠 損 値 も 標 準 では 集 計 表 の 画 面 には 現 れないなど 別 扱 いされる 場 合 がほとんどです 欠 損 を 表 す 値 を"999999" と 入 力 するような 他 のシステムから SAS に 乗 り 換 える 場 合 は SAS の 欠 損 値 を 考 慮 した 変 換 が 必 要 です 欠 損 値 を 定 数 で 割 り 当 てます (プログラム 1.1-9) data kesson; a=""; b=" "; c=" "; d=.; 10 欠 損 値 にも 比 較 順 序 があり._<.<.A< <.Z の 順 となっています 12
e=.a; proc print data=kesson; proc contents data=kesson; (PRINT アウトプット) OBS a b c d e 1. A (CONTENTS アウトプットの 一 部 ) 変 数 と 属 性 の 昇 順 リスト # 変 数 タイプ 長 さ 1 a 文 字 1 2 b 文 字 1 3 c 文 字 2 4 d 数 値 8 5 e 数 値 8 カードデータから 欠 損 値 を 入 力 します fujita さんの 性 別 と suzuki さんの 年 齢 と tanaka さんの 体 重 を 欠 損 値 として 入 力 します ( 注 意 :このようなカードイメージデータからのリスト 入 力 方 法 のときは ブラン クはデータの 区 切 り 文 字 として 認 識 されるため 文 字 タイプ 変 数 の 欠 損 値 もピリオド 1 個 で 与 えます ) (プログラム 1.1-10) data sample; input ID name $ sex $ age height weight; cards; 001 fujita. 30 175 70 002 suzuki F. 168 59 003 takahashi M 32 180 85 004 tanaka M 40 178. ; proc means data=sample; /* 基 本 統 計 を 計 算 するプロシジャ*/ proc freq data=sample; table sex; MEANS プロシジャ 変 数 N 平 均 標 準 偏 差 最 小 値 最 大 値 --------------------------------------------------------------------------- ID 4 2.5000000 1.2909944 1.0000000 4.0000000 age 3 34.0000000 5.2915026 30.0000000 40.0000000 height 4 175.2500000 5.2519838 168.0000000 180.0000000 weight 3 71.3333333 13.0511813 59.0000000 85.0000000 FREQ プロシジャ 累 積 累 積 sex 度 数 パーセント 度 数 パーセント ------------------------------------------------------- 13
F 1 33.33 1 33.33 M 2 66.67 3 100.00 欠 損 値 の 度 数 = 1 [エラー 対 応 ] ログはプログラムの 実 行 状 況 を 報 告 する 役 割 を 持 ち エラー(ERROR) 警 告 (WARNING) ノート(NOTE)の 各 メッセージにより 実 行 状 況 を 確 認 できます これまでの 例 ではエラーと 警 告 は 発 せられず ノートのみのメッセージとなっており 少 なくとも 文 法 的 なエラーや 実 行 時 のエラーは 出 現 しなかったということを 意 味 しています ただし 意 図 した 結 果 が 得 られたかどうかは ノートに 記 された 作 成 されたデータセットのオブザベーション 数 と 変 数 の 数 が1つの ポイントとなります 特 に 作 成 したデータセットのオブザベーション 数 が 0(ゼロ)になっていないか どうかを 確 認 することが 実 際 上 は 重 要 です エラーが 無 い 場 合 でもこの 部 分 は 必 ず 確 認 しておきましょ う エラーはコンパイル 時 のエラー( 文 法 エラー)と 実 行 時 のエラーに 大 きく 分 かれます 文 法 エラー 以 下 のような 場 合 に 発 生 します キーワードのタイプミス( 存 在 しないプロシジャ 名 や 関 数 名 ステートメントやオプション) ワード 間 のブランク 忘 れ 文 末 のセミコロン(;) 忘 れ 全 角 のブランクを 入 力 してしまった 場 合 Do~End 文 のネストで 対 応 がとれていない 場 合 文 法 エラーはプログラムのコンパイル 時 に 発 見 され 実 行 は 中 止 されます このような 場 合 は 最 初 に 発 生 したエラーメッセージの 近 辺 に 注 意 してタイプミス 全 角 ブランクの 有 無 セミコロンの 有 無 などを 調 べ て 訂 正 します なお よりやっかいなのは 引 用 符 ("または')が 片 方 閉 じていないままになっている 場 合 やマクロ 処 理 を 行 っている 場 合 で 問 題 が 起 きた 場 合 です このような 場 合 はエラーメッセージすら 出 てこないときがあり 何 度 サブミットを 行 っても SAS からの 応 答 が 無 い 状 態 になることがあります この 場 合 は 以 下 のおま じないで 解 決 できる 場 合 がありますので 試 してください (おまじないのプログラム) ;*';*";*/;quit; 実 行 時 エラーは 以 下 のような 場 合 に 発 生 します データ 入 力 において 読 み 取 ろうとするデータ 形 式 と 読 み 取 り 形 式 が 異 なる 対 応 がとれない 場 合 など 未 定 義 の 変 数 に 対 する 処 理 を 行 おうとした 場 合 無 効 な 関 数 の 引 数 の 指 定 ( 存 在 しない 日 付 を 指 定 した 場 合 など) ゼロで 割 る 処 理 を 行 った 場 合 このような 場 合 実 行 は 中 断 されず 結 果 を 欠 損 値 に 設 定 するなどして 実 行 が 続 きます 14
なお Windows のコンピュータ 資 源 不 足 や 書 き 込 み 禁 止 などのファイルセキュリティなどの 理 由 でエラ ーが 発 生 する 場 合 もあります 15
1.2 データ 読 取 り 変 数 作 成 と 横 方 向 の 集 計 処 理 ~ FILENAME LIBNAME INPUT SET IMPORT EXPORT 割 り 当 てステート メント 集 計 関 数 データセットオプション PRINT SORT プロシジャ SAS でデータの 集 計 や 分 析 等 の 処 理 を 行 うためには 通 常 集 計 や 分 析 に 用 いるデータを 一 旦 SAS デー タセットに 読 み 込 む 必 要 があります SAS ファイル 以 外 のファイルを SAS から 見 て 外 部 ファイル と 呼 んでいます まず 外 部 ファイルから SAS データセットにデータを 読 み 込 むために 用 いる DATA ステップの SAS ステートメントとして 重 要 な INPUT ステートメントと INFILE ステートメントを 主 に 学 びます 次 に SAS データセットからのデータの 読 込 を 行 う SET ステートメント CSV 形 式 など の 外 部 ファイルの 入 力 に 用 いることができる IMPORT プロシジャなどを 学 びます さらに DATA ステップで 用 いるステートメントの 中 で 割 り 当 てステートメントその 他 のプログラミングス テートメントの 一 部 関 数 の 一 部 データセットオプションなどを 学 びます また PRINT, SORT などのプロシジャの 文 法 を 理 解 します [INPUT ステートメントによるデータの 読 み 取 り] まず プログラムの 中 に 読 み 取 りデータを 書 いた 例 から 始 めます 冒 頭 に 出 てきたプログラム 1.1-2 をもう 一 度 取 り 上 げます 下 記 のプログラムをエデイタに 呼 び 出 してください なお そのエデイタ 画 面 をアクティブにした 上 で 書 いたプログラムのどの 部 分 も 選 択 せずにサブミット すると そのエディタ 画 面 に 書 かれたプログラム 全 部 が 一 度 にサブミットされます エラーが 発 生 したと きは 上 手 くいった DATA ステップや PROC ステップ 部 分 は 再 実 行 する 必 要 ありませんので 修 正 した プログラム 部 分 を 含 む DATA ステップもしくは PROC ステップ 以 降 を 選 択 してからサブミットしてくだ さい また /* */ で 囲 んだテキスト 部 分 はコメントですので 入 力 してもしなくても 結 構 です (プログラム 1.1-2) data sample; /*データセットの 作 成 */ input ID name $ sex $ age height weight; /* 変 数 の 名 前 と 型 を 決 めて 読 み 込 みを 実 行 する 文 */ cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001 fujita M 30 175 70 002 suzuki F 29 168 59 003 takahashi M 32 180 85 004 tanaka M 40 178 77 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ SAS システム 1 2010 年 10 月 10 日 日 曜 日 午 後 03 時 29 分 36 秒 OBS ID name sex age height weight 1 1 fujita M 30 175 70 2 2 suzuki F 29 168 59 3 3 takahash M 32 180 85 4 4 tanaka M 40 178 77 16
(DATA ステートメント) 宣 言 ステートメント DATA ステップを 開 始 し 作 成 する SAS データセット 名 を 明 示 的 に 指 定 します ここでは sample という 名 前 の SAS データセットを WORK ライブラリに 1 個 作 成 するという 宣 言 をしています DATA ステップ は 1 つの DATA ステートメントで 開 始 し RUN ステートメントで 明 示 的 に 終 了 します また 他 の DATA ステートメントや PROC ステートメントに 遭 遇 することによっても 終 了 します データセット 名 を 省 略 すると _data_ という 自 動 SAS データセット 名 が 指 定 されたものとみなされま す これは SAS セッションの 最 初 に 指 定 された 場 合 は DATA1 という 名 前 2 番 目 は DATA2, 以 下 同 様 に DATA3,...,DATAn という 名 前 の SAS データセットを 作 成 します ( 例 ) data; set sample; 同 時 に 複 数 の SAS データセット 名 を 指 定 可 能 です 入 力 データから 条 件 検 索 によって 別 々のデータセ ットを 作 成 する 場 合 などに 使 います ( 例 ) data male female; set sample; if sex="m" then output male; else output female; データセットを 作 成 しないで DATA ステップを 実 行 する 特 殊 なデータセット 名 _null_ があります ( 例 ) data _null_; set sample; if sex="m" then put _all_; (INPUT ステートメント) 実 行 ステートメント INPUT ステートメントは 外 部 データのレコード 行 から どのデータをどういう 変 数 名 と 型 で 読 み 取 るか を 指 定 し 実 行 するステートメントです ここでは リスト 入 力 と 呼 ばれる 最 も 単 純 な 方 法 で 読 み 取 り たい 項 目 の 変 数 名 と 型 をリストするだけの 指 定 を 行 っています (CARDS ステートメント) 宣 言 ステートメント CARDS ステートメントは INPUT ステートメントで 読 み 込 むデータはこのステートメントの 次 の 行 から 1 個 のセミコロン(;)が 書 かれた 行 の 間 に 入 っていることを 知 らせるステートメントです [INPUT ステートメントの 指 定 方 法 ] 3 通 りの 入 力 方 法 と 6 つの 修 飾 子 (modifier) (@,@@,+,#,:,/)について 学 びます [(1)リスト 入 力 ] (INPUT ステートメントの 指 定 ) input ID name $ sex $ age height weight; データ 項 目 はブランク 1 個 以 上 を 区 切 り 文 字 としてテキスト 形 式 で 並 んでいる 場 合 に 用 いることができま す CARDS ステートメントで 入 力 するデータがある 場 合 は 指 定 が 簡 単 なので 良 く 使 われます データ 項 目 はブランクで 区 切 られていますのでリスト 入 力 向 きです (1 行 目 のデータ 行 ) 001 fujita M 30 175 70 データ 項 目 の 並 び 順 に 対 応 して SAS データセットになる 変 数 名 と 型 ( 文 字 型 の 場 合 は$, 数 値 型 の 場 合 は 何 も 指 定 しません.)を 順 次 指 定 していきます. 欠 損 値 はピリオド 1 個 で 入 力 されている 必 要 があります. 上 記 データの 並 びに 対 応 して ID=1 ( 数 値 ) name="fujita" ( 文 字 ) 17
sex="m" ( 文 字 ) age=30 ( 数 値 ) height=175 ( 数 値 ) weight=70 ( 数 値 ) の 値 を 持 つオブザベーションが input ステートメントによって 読 み 込 まれます このリスト 入 力 には 次 の 制 約 があります (A) 文 字 型 データを 読 む 際 に 8 バイトの 長 さに 切 られます ("takahashi"は"takahash" と 最 初 の 8 文 字 ま でしか 読 まれていません ) (B)テキスト 形 式 の 値 しか 読 み 取 れません(バイナリ 形 式 などの 編 集 形 式 のデータは 読 み 取 れません) (A)の 問 題 は 次 のカラム 入 力 やフォーマット 入 力 でも 解 決 できますが フォーマット 入 力 とリスト 入 力 を ミックスしたコロン(:)フォーマット 指 定 付 きリスト 入 力 が 実 用 的 です なおコロン(:)は INPUT ステー トメントで 使 える 修 飾 子 の 1 つです [コロンフォーマット 指 定 による INPUT ステートメントの 指 定 ] (プログラム 1.2-1) data sample; /*データセットの 作 成 */ input ID name :$10. sex :$1. age height weight; cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001 fujita M 30 175 70 002 suzuki F 29 168 59 003 takahashi M 32 180 85 004 tanaka M 40 178 77 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ OBS ID name sex age height weight 1 1 fujita M 30 175 70 2 2 suzuki F 29 168 59 3 3 takahashi M 32 180 85 4 4 tanaka M 40 178 77 name :$10. のコロンフォーマット 指 定 付 きリスト 入 力 を 行 ったため takahashi とちゃんと 入 力 できて います (B)の 問 題 はフォーマット 入 力 で 解 決 できます [(2)カラム 入 力 ] 外 部 データレコード 上 の 各 項 目 のカラム 位 置 が 決 まっているテキスト 形 式 データを 入 力 する 場 合 に 使 いま す 読 み 取 りたいカラムの 項 目 だけ 選 択 して 読 み 取 ることができます カラム 入 力 は INPUT ステートメントに 変 数 名 タイプ($もしくは 指 定 なし) 開 始 カラム 位 置 - 終 了 カラム 位 置 を 1 セットとして 読 み 取 りたい 項 目 分 を 指 定 する 方 法 です 18
(プログラム 1.2-2) data sample; /*データセットの 作 成 */ input ID 1-3 name $4-13 sex $14 age 15-16 height 17-19 weight 20-21 sahw $14-21; cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001fujita M3017570 002suzuki F2916859 003takahashi M3218085 004 tanaka M4017877 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ OBS ID name sex age height weight sahw 1 1 fujita M 30 175 70 M3017570 2 2 suzuki F 29 168 59 F2916859 3 3 takahashi M 32 180 85 M3218085 4 4 tanaka M 40 178 77 M4017877 [(3)フォーマット 入 力 ] フォーマット 入 力 は INPUT ステートメントに @カラムポインター 位 置 変 数 名 読 み 取 り 編 集 形 式 (INFORMAT) 名. を 1 セットとして 読 み 取 りたい 項 目 分 を 指 定 する 方 法 です @は INPUT ステートメントで 使 える 修 飾 子 の 1 つで その 行 における 読 み 取 りポインタの 絶 対 カラム 位 置 を 与 えます @の 後 には 正 の 整 数 もしくは 正 の 整 数 を 値 に 持 つ 変 数 名 を 指 定 します (プログラム 1.2-3) data sample; /*データセットの 作 成 */ input @14 sex $1. @4 name $10. @1 ID 3.; cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001fujita M3017570 002suzuki F2916859 003takahashi M3218085 004 tanaka M4017877 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ OBS sex name ID 1 M fujita 1 2 F suzuki 2 3 M takahashi 3 4 M tanaka 4 フォーマット 入 力 は 外 部 データ 項 目 がどのような 編 集 形 式 であってもほとんど 読 み 取 ることができるとい う 意 味 で SAS が 大 変 強 力 なデータ 入 力 編 集 機 能 を 持 っている 証 の 1 つになっています SAS では 特 定 の 編 集 形 式 で 書 かれた 外 部 データ 値 を SAS 変 数 値 に 読 み 込 む 場 合 の 編 集 形 式 の 指 定 をインフォーマット( 入 19
力 フォーマット)と 呼 んでいます 逆 に SAS 変 数 値 を 指 定 の 編 集 形 式 で 外 部 データ 値 として 書 き 出 す 場 合 の 編 集 形 式 の 指 定 をフォーマット( 出 力 フォーマット)と 呼 んでいます [ 別 表 7] に 主 要 なインフォーマット [ 別 表 6] にフォーマットの 一 覧 を 表 示 してますので 見 てみましょ う [+ 相 対 カラム 位 置 移 動 修 飾 子 ] @ポインタ 指 定 がカラムの 絶 対 位 置 指 定 であったのに 対 し + 修 飾 子 は 同 一 行 の 中 でのポインタを 相 対 的 に 移 動 させる 機 能 を 持 っています +の 後 には 整 数 ( 負 の 整 数 も 可 )もしくは 整 数 を 値 として 持 つ 変 数 名 を 指 定 します (プログラム 1.2-4) data sample; /*データセットの 作 成 */ input @14 sex $1. +2 height 3. +(-6) sahw $8. @1 ID 3.; cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001fujita M3017570 002suzuki F2916859 003takahashi M3218085 004 tanaka M4017877 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ OBS sex height sahw ID 1 M 175 M3017570 1 2 F 168 F2916859 2 3 M 180 M3218085 3 4 M 178 M4017877 4 [ 複 数 レコードをあたかも 1 レコードとして 読 み 取 る 場 合 ] 1 人 の 顧 客 属 性 項 目 が 複 数 レコード 行 にわたって 書 かれているような 場 合 修 飾 子 の 1 つである # 行 ポイ ンタ 指 定 を 用 いるとうまく 読 み 込 むことができます (プログラム 1.2-5) data sample; /*データセットの 作 成 */ input #1 @1 ID 3. @4 name $10. #2 @1 sex $1. @7 weight 2.; cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001fujita M3017570 002suzuki F2916859 003takahashi M3218085 004 tanaka M4017877 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ 20
OBS ID name sex weight 1 1 fujita M 70 2 2 suzuki F 59 3 3 takahashi M 85 4 4 tanaka M 77 # 行 ポインタ 修 飾 子 が INPUT ステートメントに 出 現 すると 外 部 レコードの 行 は #ポインタの 最 大 値 の 行 数 を1 単 位 として 読 み 込 むモードになります #の 後 には 正 の 整 数 もしくは 正 の 整 数 値 を 持 つ 変 数 名 を 指 定 します [ 複 数 の INPUT ステートメントの 指 定 ] #ポインタと@ポインタを 使 うと 複 数 行 にわたって どの 行 のどのカラム 位 置 からでも 自 由 にデータを 読 みとれますし 読 み 取 りポインタの 位 置 を 前 後 左 右 自 由 に 行 き 来 できるという 利 点 があります しかしながら 複 数 行 のレコードを1 単 位 として 1 番 目 の 行 から 順 に 読 み 取 る 場 合 は #ポインタを 用 いずに 複 数 の INPUT ステートメントを 書 いて 読 み 込 むことができます (プログラム 1.2-6) data sample; /*データセットの 作 成 */ input @1 ID 3. @4 name $10.; input @1 sex $1. @7 weight 2.; cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 001fujita M3017570 002suzuki F2916859 003takahashi M3218085 004 tanaka M4017877 ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ OBS ID name sex weight 1 1 fujita M 70 2 2 suzuki F 59 3 3 takahashi M 85 4 4 tanaka M 77 ここで 重 要 なのは 各 INPUT ステートメントの 最 後 のセミコロン(;)はそれぞれ 読 んでいる 外 部 データ 行 の 読 込 を 終 了 して 次 の 外 部 データ 行 の 最 初 のカラムに 読 込 ポインタを 進 める 合 図 だということです なお / 修 飾 子 を 用 いて 以 下 のように 指 定 しても 改 行 して 読 み 取 る 指 定 になります input ID 3. @4 name $10. / sex $1. @7 weight 2.; 注 : INPUT ステートメントや/ 修 飾 子 の 後 の 最 初 の@1 は 省 略 できます 21
[@;で 終 わる INPUT ステートメント] @ 修 飾 子 はカラム 絶 対 位 置 を 指 定 する 役 割 の 他 に INPUT ステートメントを@;で 終 了 させた 場 合 はポイ ンタを 次 の 行 に 移 動 させず 直 前 のデータ 読 み 取 り 位 置 に 留 めておく 機 能 があります 例 えば 最 初 の 1 カラム 目 の 文 字 を 検 索 して 値 によって 次 の 読 み 取 り 項 目 を 変 更 するような 場 合 に 有 用 です (プログラム 1.2-6) data sample; /*データセットの 作 成 */ input point 1. @; input +point char $1.; cards; /*データはこれ 以 降 に 入 力 するという 意 味 の 文 */ 1abcdefghijklmn 5abcdefghijklmn ; /*データをCARDS 文 で 入 力 する 場 合 のデータ 入 力 終 了 の 合 図 */ proc print data=sample; /*データ 部 を 表 示 するプロシジャ*/ OBS point char 1 1 b 2 5 f [@@;で 終 わる INPUT ステートメント] @@ 修 飾 子 で 終 わる INPUT ステートメントは カードイメージデータからデータを 入 力 する 場 合 に 特 に 便 利 です (プログラム 1.2-7) data sample; input x y @@; cards; 1 2 3 4 5 6 7 8 9 10 11 12 ; proc print data=sample; OBS x y 1 1 2 2 3 4 3 5 6 4 7 8 5 9 10 6 11 12 @@;で 終 わる INPUT ステートメントは DATA ステップの 次 のループに 対 しても 外 部 データ 上 のポインタ 保 留 位 置 を 維 持 する 役 割 があります @;で 終 わる INPUT ステートメントに 変 えて 実 行 してみてください 22
(プログラム 1.2-8) data sample; input x y @; cards; 1 2 3 4 5 6 7 8 9 10 11 12 ; proc print data=sample; OBS x y 1 1 2 2 9 10 @1 個 だと DATA ステップはデータ 行 の 数 だけのループになります 以 上 で INPUT ステートメントの 説 明 は 終 了 です [FILENAME ステートメントと INFILE ステートメント] 次 は CARDS ステートメントの 中 ではなく 外 部 ファイルにデータがある 場 合 にデータを 読 む 方 法 を 学 びます 外 部 ファイルにアクセスする 場 合 アクセス 先 を 指 定 する 実 行 ステートメント(INFILE ステー トメント( 入 力 )と FILE ステートメント( 出 力 ))において そのファイルの 物 理 パス 名 を 記 述 する 代 わりに あらかじめ FILENAME ステートメントでそのファイルをアクセスするためのファイル 参 照 名 を 定 義 して おき INFILE ステートメントや FILE ステートメントでファイル 参 照 名 を 使 用 することができます SAS プログラムでアクセスする 外 部 ファイルを SAS プログラムコードの 冒 頭 に 書 いておけるのでプログラム が 大 変 読 みやすくスマートになります 練 習 用 に 以 下 のデータ 項 目 を SAS エディタもしくはメモ 帳 で 作 成 して ユーザディレクトリ (C:USERS ユーザ 名 DOCUMENTS My SAS Files 9.1 など)の 中 に sample1.dat という 名 前 で 保 存 して ください (sample1.dat の 内 容 ) 001 fujita M 30 175 70 002 suzuki F 29 168 59 003 takahashi M 32 180 85 004 tanaka M 40 178 77 (プログラム 1.2-9) 注 意 ユーザ 名 の 箇 所 はあなたのログオンユーザ 名 を 入 力 してください filename in "c:\users\ユーザ 名 \documents\my sas files\9.1"; data sample; infile in(sample1.dat); input ID name $ sex $ age height weight; proc print data=sample; (ログ) 23
179 filename in "c:\users\hideo\documents\my sas files\9.1"; 180 data sample; 181 infile in(sample1.dat); 182 input ID name $ sex $ age height weight; NOTE: 入 力 ライブラリ IN: ディレクトリ=c:\users\ユーザ 名 \documents\my sas files\9.1 NOTE: 入 力 ファイル IN(sample1.dat) : ファイル 名 =c:\users\ユーザ 名 \documents\my sas files\9.1\sample1.dat, レコードフォーマット=V, 論 理 レコード 長 =256 NOTE: 4 レコードを 入 力 ライブラリ IN から 読 み 込 みました 最 小 レコード 長 は 22 です 最 大 レコード 長 は 25 です NOTE: 4 レコードを 入 力 ファイル IN(sample1.dat) から 読 み 込 みました 最 小 レコード 長 は 22 です 最 大 レコード 長 は 25 です NOTE: データセット WORK.SAMPLE は 4 オブザベーション 6 変 数 です NOTE: DATA ステートメント 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.04 秒 CPU 時 間 0.00 秒 183 proc print data=sample; 184 NOTE: データセット WORK.SAMPLE から 4 オブザベーションを 読 み 込 みました NOTE: PROCEDURE PRINT 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.06 秒 CPU 時 間 0.01 秒 OBS ID name sex age height weight 1 1 fujita M 30 175 70 2 2 suzuki F 29 168 59 3 3 takahash M 32 180 85 4 4 tanaka M 40 178 77 (FILENAME ステートメント 指 定 方 法 ) 宣 言 ステートメント FILENAME ファイル 参 照 名 " 物 理 パス 名 "; (INFILE ステートメントの 指 定 方 法 ) 実 行 ステートメント INFILE ファイル 参 照 名 オプション; ただし ファイル 参 照 名 は 上 記 プログラム 例 のようにフォルダに 指 定 した 場 合 は (データセット 名 )を 指 定 しフォルダ 内 の 特 定 のファイルを 参 照 させる 必 要 があります ファイル 参 照 名 は SAS 名 の 制 約 を 受 けます ただし 長 さは 8 文 字 以 内 です また INFILE ステートメントで 指 定 できる 特 殊 なファイル 参 照 名 として CARDS があります これは CARDS ステートメントの 後 に 入 力 したデータのレコード 形 式 (dsd や dlm=オプション)を 指 定 でき 24
るようにするためです (ただしカードイメージデータの 最 大 レコード 長 はデフォルトの 256 を 超 えて 設 定 不 能 です ) その 他 EXCEL ファイルを 読 むときのための DDE 指 定 などがあります [INFILE ステートメントで 良 く 使 うオプション] lrecl= 論 理 レコード 長 省 略 すると 256 が 設 定 されますので 固 定 長 の 外 部 ファイルを 読 むときはその 長 さ csv 形 式 などの 可 変 長 の 外 部 ファイル を 読 む 場 合 は lrecl=32000 と 大 きな 値 を 指 定 します recfm=レコードフォーマット OS 環 境 によって 指 定 可 能 な 値 が 異 なりますが Windows 環 境 では f( 固 定 長 ),v( 可 変 長 ),n( 不 定 長 )の 3 つのいずれかになります dsd オプション と dlm=" 区 切 り 文 字 " オプション csv 形 式 の 可 変 長 レコードを 読 むときに 必 要 になります (ただし 後 述 の IMPORT プロシジャのおかげで csv 形 式 のファイルは DATA ステップを 使 わなくても 読 めますが 変 数 のタイプなどを 的 確 に 指 定 したい 場 合 などのために 知 っておいた 方 が 良 いと 思 います ) (プログラム 1.2-10) INFILE CARDS 指 定 と dsd,dlm=オプション data sample; infile cards dsd dlm=","; input ID name $ sex $ age height weight; cards; 001,fujita,M,30,175,70 002,suzuki,F,29,168,59 003,takahashi,M,32,180,85 004,tanaka,M,40,178,, ; proc print data=sample; OBS ID name sex age height weight 1 1 fujita M 30 175 70 2 2 suzuki F 29 168 59 3 3 takahash M 32 180 85 4 4 tanaka M 40 178. 以 上 のように 外 部 ファイルをアクセスする 場 合 読 み 取 りは INFILE ステートメントと INPUT ステー トメントを 用 います ( 逆 に 後 述 するように 書 き 込 みは FILE ステートメントと PUT ステートメント を 用 います ) なお FILENAME ステートメントを 省 略 して 以 下 のように 書 いても 実 行 できます data sample; infile "c:\users\hideo\documents\my sas files\9.1\sample1.dat"; input ID name $ sex $ age height weight; 25
しかしながら プログラムの 冒 頭 で そのプログラムがアクセスする 物 理 ファイルをすべてあらかじめ FILENAME ステートメントでファイル 参 照 名 を 定 義 しておくと プログラムが 見 やすくなります [SET ステートメントによる SAS データセットの 読 込 み] FILENAME ステートメント CARDS ステートメント INFILE ステートメント INPUT ステートメント は 外 部 データの 読 込 に 用 いられるステートメントでした 一 方 SAS データセットの 値 を 読 み 込 むステ ートメントは LIBNAME ステートメントと SET MERGE UPDATE ステートメントです 一 旦 SAS データセットにデータが 格 納 されていると SAS データセットはデータ 部 以 外 にディクショナ リ 部 を 持 っていますので データセット 名 を 指 定 するだけで SAS はすべての 項 目 の 情 報 が 分 かってしま うということです SET MERGE UPDATE の 各 ステートメントの 違 いは 後 で 学 ぶことになりますが ここでは 単 一 の SAS データセットを 読 み 込 む 場 合 は LIBNAME ステートメントと SET ステートメントを 使 えば 良 いということを 覚 えておけば 十 分 です プログラム 1.1-6 で 既 に libname の 基 本 は 出 ていますので SET ステートメントといくつかのステートメ ントを 使 った 例 を 実 行 してみます (プログラム 1.2-11) data sample2; set sample; if sex="f" then output; else delete; proc print data=sample2; OBS ID name sex age height weight 1 2 suzuki F 29 168 59 (SET ステートメントの 指 定 方 法 ) 実 行 ステートメント SET SAS データセット 名 オプション; SAS データセット 名 複 数 の SAS データセットをブランクで 区 切 って 指 定 できます オプション end= 変 数 名 最 後 のオブザベーションを 読 んだ 時 点 で 指 定 の 変 数 値 =1 となります (IF ステートメント) 実 行 ステートメント (else ステートメント) 実 行 ステートメント 条 件 選 択 を 行 うステートメントです 別 途 詳 しく 学 びます 26
(OUTPUT ステートメントの 指 定 方 法 ) 実 行 ステートメント SAS データセットにプログラムデータベクトルの 値 を1オブザベーションとして 書 き 込 みます OUTPUT 出 力 SAS データセット 名 ; 出 力 SAS データセット 名 には 複 数 の SAS データセット 名 をブランクで 区 切 って 指 定 できます ( 同 じオ ブザベーションが 出 力 されます ) (DELETE ステートメント) 実 行 ステートメント このステートメント 実 行 時 点 でオブザベーションの 書 き 出 しを 行 わずに DATA ステップループの 最 初 に 戻 ります (プログラムデータベクトルの 値 は DATA ステップのループに 戻 った 時 点 ですべて 欠 損 値 にリセ ットされます ) なお OUTPUT ステートメントが 明 示 的 に1つでも 存 在 すれば DATA ステップの 最 後 の OUTPUT ステ ートメントの 自 動 挿 入 は 行 われませんので この 例 では else delete; は 無 くても 結 果 は 同 じになります しかし あった 方 が 明 示 的 です [IMPORT プロシジャと EXPORT プロシジャ] テキストファイル 特 に csv ファイル(Comma Separeted Values, カンマ 区 切 りデータ)を 読 み 取 るとき 重 宝 するプロシジャです まず EXPORT プロシジャを 用 いて SAS データセット SAMPLE の 内 容 を CSV 形 式 ファイルにします (プログラム 1.2-12) proc export data=sample outfile="sample.csv" replace; メモ 帳 などで 現 在 の 作 業 フォルダ(マイドキュメント)の 下 に sample.csv が 出 来 ていることを 確 認 してくだ さい 1 行 目 に SAS データセットの 変 数 名 が 書 き 出 されている 点 に 注 意 してください 残 念 ながら 変 数 名 の 書 き 出 しを 抑 制 するオプションはありません そうしたい 場 合 は 以 下 のように options source2; を 指 定 してから proc export を 実 行 すると ログに export を 実 行 する DATA ステッププログラムが 出 現 しますので これを 編 集 して 再 実 行 すると 良 いでしょ う 27
(プログラム 1.2-13) EXPORT プロシジャを DATA ステップに 展 開 したログを 得 る options source2; proc export data=sample outfile="sample.csv" x; (ログ) 143 /********************************************************************** 144 * プロダクト: SAS 145 * バージョン: 9.1 146 * 作 成 者 : 外 部 ファイルインターフェイス 147 * 作 成 日 : 14OCT10 148 * 説 明 : 生 成 された SAS データステップ コード 149 * テンプレート ソース: ( 指 定 なし) 150 ***********************************************************************/ 151 data _null_; 152 set SAMPLE end=efieod; 153 %let _EFIERR_ = 0; /* エラー 検 出 のマクロ 変 数 を 設 定 します */ 154 %let _EFIREC_ = 0; /* エクスポートレコードカウントのマクロ 変 数 をクリアします */ 155 file 'sample.csv' delimiter=',' DSD DROPOVER lrecl=32767; 156 format ID best12. ; 157 format name $8. ; 158 format sex $8. ; 159 format age best12. ; 160 format height best12. ; 161 format weight best12. ; 162 if _n_ = 1 then /* 列 名 を 書 き 出 します */ 163 do; 164 put 165 'ID' 166 ',' 167 'name' 168 ',' 169 'sex' 170 ',' 171 'age' 172 ',' 173 'height' 174 ',' 175 'weight' 176 ; 177 end; 178 do; 179 EFIOUT + 1; 180 put ID @; 181 put name $ @; 182 put sex $ @; 183 put age @; 184 put height @; 185 put weight ; 186 ; 187 end; 188 if _ERROR_ then call symput('_efierr_',1); /* エラー 検 出 のマクロ 変 数 を 設 定 します */ 189 if EFIEOD then call symputx('_efirec_',efiout); 28
190 上 記 ログをエディタ 画 面 にコピーし 上 記 ログ 番 号 の 162 行 目 から 177 行 目 に 相 当 する 箇 所 を 削 除 して かつ 156 行 目 の file "sample.csv"; の 箇 所 を file "XXXXX.csv"; に 変 更 した 上 でサブミットします (プログラム 1.2-14) ログをエディタにコピーし 行 番 号 を 削 除 し 不 要 な 箇 所 を 削 除 してサブミット /********************************************************************** * プロダクト: SAS * バージョン: 9.1 * 作 成 者 : 外 部 ファイルインターフェイス * 作 成 日 : 14OCT10 * 説 明 : 生 成 された SAS データステップ コード * テンプレート ソース: ( 指 定 なし) ***********************************************************************/ data _null_; set SAMPLE end=efieod; %let _EFIERR_ = 0; /* エラー 検 出 のマクロ 変 数 を 設 定 します */ %let _EFIREC_ = 0; /* エクスポートレコードカウントのマクロ 変 数 をクリアします */ file 'XXXXX.csv' delimiter=',' DSD DROPOVER lrecl=32767; format ID best12. ; format name $8. ; format sex $8. ; format age best12. ; format height best12. ; format weight best12. ; do; EFIOUT + 1; put ID @; put name $ @; put sex $ @; put age @; put height @; put weight ; ; end; if _ERROR_ then call symput('_efierr_',1); /* エラー 検 出 のマクロ 変 数 を 設 定 します */ if EFIEOD then call symputx('_efirec_',efiout); (EXPORT プロシジャの 指 定 方 法 ) SAS データセットの 値 を 外 部 テキストファイルに 書 き 出 す PROC EXPORT DATA= 入 力 SASデータセット 名 OUTFILE=" 出 力 外 部 データセット 名 " オプション; (PROC EXPORT ステートメントの 良 く 使 うオプション) 29
REPLACE 既 存 の 出 力 ファイルの 内 容 を 置 き 換 えることを 許 可 します 次 に 今 書 き 込 んだ CSV 形 式 ファイルを INPORT プロシジャを 用 いて SAS データセットに 読 み 込 みます (プログラム 1.2-15) IMPORT プロシジャの 実 行 proc import datafile="sample.csv" out=samplex replace; proc print data=samplex; OBS ID name sex age height weight 1 1 fujita M 30 175 70 2 2 suzuki F 29 168 59 3 3 takahash M 32 180 85 4 4 tanaka M 40 178. 読 み 取 る sample.csv の 1 行 目 を SAS 変 数 名 とみなして 自 動 的 に 読 み 取 っている 点 に 注 意 してください (IMPORT プロシジャ) 外 部 テキストファイルを SAS データセットに 読 み 込 む PROC IMPORT DATAFILE=" 入 力 外 部 データセット 名 " OUT= 出 力 sas データセット 名 オプション; オプションデータソースステートメント; (PROC IMPORT ステートメントの 良 く 使 うオプション) REPLACE 既 存 の 出 力 SAS データセットの 内 容 を 置 き 換 えることを 許 可 します ( 良 く 使 われるオプションデータソースステートメント) GETNAMES=YES NO 1 行 目 を 変 数 名 として 読 み 取 るかどうかを 選 択 します デフォルトは YES です GUESSINGROWS=1-32767 変 数 の 型 の 推 測 を 読 み 取 る 外 部 データを 何 行 読 んでから 決 定 するかを 指 定 します DATAROW= 正 の 整 数 何 行 目 から 読 み 始 めるかを 指 定 します (プログラム 1.2-16) 1 行 目 を 変 数 名 として 読 む getnames=yes(デフォルト)の 効 果 proc import datafile="xxxxx.csv" out=samplex replace; proc print data=samplex; OBS _ fujita M _0 _75 VAR6 1 2 suzuki F 29 168 59 2 3 takahash M 32 180 85 3 4 tanaka M 40 178. (プログラム 1.2-17) 1 行 目 をデータ 行 として 読 む getnames=no 指 定 の 追 加 30
proc import datafile="xxxxx.csv" out=samplex replace; getnames=no; proc print data=samplex; OBS VAR1 VAR2 VAR3 VAR4 VAR5 VAR6 1 1 fujita M 30 175 70 2 2 suzuki F 29 168 59 3 3 takahash M 32 180 85 4 4 tanaka M 40 178. [Excel への 書 き 出 し] Excel に 直 接 書 出 すには DDE を 使 います 11 DDE(Dynamic Data Exchange) は Windows の 機 能 の 1 つで 対 応 する 別 々のアプリケーション 間 での 動 的 なデータ 交 換 機 能 を 実 行 します SAS も Excel も DDE に 対 応 していますので SAS からは FILENAME ステートメントで dde エンジンを 指 定 して 呼 び 出 します ) Excel を 起 動 し Sheet1 シートが 開 いた 状 態 にあることを 確 認 してから 以 下 のプログラムを 実 行 してく ださい (プログラム 1.2-18) DDE を 使 った Excel への 書 き 込 み filename out dde "Excel Sheet1!r1c1:r4c6"; data _null_; set sample; file out lrecl=32000; put id name sex age height weight; FILE ステートメントと put ステートメントは INFILE ステートメントと INPUT ステートメントの 逆 に DATA ステップで 外 部 ファイルにデータを 書 きだすためのステートメントです (FILE ステートメント) 実 行 ステートメント INFILE ステートメントと 同 じようなオプションが 使 えます (PUT ステートメント) 実 行 ステートメント INPUT ステートメントと 同 じような 指 定 (リスト 出 力 カラム 出 力 フォーマット 出 力 および@,#などの 11 EXPORT プロシジャで 直 接 書 き 込 みを 行 うためには SAS/ACCESS to PC File Formats プロダクトが 必 要 です 31
修 飾 子 )が 使 えます [ 割 り 当 てステートメント] 一 般 のプログラミングステートメントにあるものと 同 じような 実 行 ステートメントです 変 数 名 = 式 ; 右 辺 の 式 の 値 を 左 辺 の 変 数 の 値 に 割 り 当 てます [ 集 計 関 数 ] データセットのデータ 値 を 横 方 向 に 集 計 したい 場 合 は DATA ステップの 集 計 関 数 を 用 います 統 計 ( 集 計 ) CSS 修 正 済 平 方 和 x=css(5,10,20,16,0,5); CV 変 動 係 数 (% 表 示 ) x=cv(5,10,20,16,0,5); KURTOSIS 尖 度 x=kurtosis(5,10,20,16,0,5); MAX 最 大 値 x=max(5,10,20,16,0,5); MEAN 平 均 値 x=mean(5,10,20,16,0,5); MIN 最 小 値 x=min(5,10,20,16,0,5); N 非 欠 損 値 の 数 を 返 す n=n(1,3,.,5,10); NMISS 欠 損 値 の 数 を 返 す nmiss=nmiss(1,3,.,5,10); RANGE 範 囲 x=range(5,10,20,16,0,5); SKEWNESS 歪 度 x=skewness(5,10,20,16,0,5); STD 標 準 偏 差 x=std(5,10,20,16,0,5); SUM 合 計 x=sum(5,10,20,16,0,5); USS 修 正 前 平 方 和 x=uss(5,10,20,16,0,5); VAR 不 偏 分 散 x=var(5,10,20,16,0,5); (プログラム 1.2-19) 集 計 関 数 の 例 data sales; input dept$ s01-s05; tot_sales=sum(s01,s02,s03,s04,s05); avr_sales=mean(of s01-s05); active_year=n(of s:); cards; A 125 100 181 201 225 B 80 115 300 262 193 C 10 11 12.. ; proc print data=sales; tot_ avr_ active_ OBS dept s01 s02 s03 s04 s05 sales sales year 1 A 125 100 181 201 225 832 166.4 5 2 B 80 115 300 262 193 950 190.0 5 3 C 10 11 12.. 33 11.0 3 sum()は 合 計 mean()は 平 均 n()は 非 欠 損 データ 件 数 を 返 す 関 数 です mean は Excel の 関 数 名 と 異 なる 点 に 注 意 [ 変 数 リスト 省 略 のための 修 飾 子 ] 32
上 記 INPUT ステートメントや 関 数 の 中 で 個 々の 変 数 名 をブランクたカンマで 区 切 ってリストする 代 わり に 変 数 名 prefix+ 数 字 - 変 数 名 pefix 数 字 の 形 式 でハイフン(-) 省 略 指 定 が 使 えます そのほかにも ハイフンハイフン (--)とコロン(:) 省 略 指 定 があります 例 ) x1-x100 変 数 x1,x2,...,x100 の 100 個 の 変 数 名 を 指 定 s03--avr_sales プログラムデータベクトルに 定 義 された 変 数 名 の 並 び 順 で s03 を 開 始 変 数 名 avr_sales を 終 了 変 数 名 と してその 間 に 存 在 する 全 変 数 名 を 指 定 s: プログラムデータベクトルに 定 義 された 変 数 の 中 でsで 始 まるすべての 変 数 名 を 指 定 [データセットオプション] SAS データセットを 読 み 書 きする 場 合 特 定 の 検 索 条 件 やインデクスをつけたり データセットにパス ワードや 圧 縮 指 定 をおこなったりすることができます これをデータセットオプションと 呼 びます (プログラム 1.2-20) データセットオプションの 例 data sales2(compress=yes password=himitsu index=(dept)); set sales(where=(tot_sales>=800)); proc contents data=sales2; data sales3; set sales2; (ログ) NOTE: データセット WORK.SALES から 2 オブザベーションを 読 み 込 みました WHERE tot_sales>=800; NOTE: データセット WORK.SALES2 は 2 オブザベーション 9 変 数 です NOTE: 圧 縮 によって データセット WORK.SALES2 のサイズを 50.00 パーセント 増 加 しました 圧 縮 時 のサイズは 3 ページです ( 非 圧 縮 時 は 2 ページが 必 要 です ) NOTE: DATA ステートメント 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.14 秒 CPU 時 間 0.01 秒 CONTENTS プロシジャ データセット 名 WORK.SALES2 オブザベーション 数 2 メンバータイプ DATA 変 数 の 数 9 エンジン V9 インデックス 数 1 作 成 日 時 2010 年 10 月 14 日 木 曜 日 午 後 03 時 36 分 50 秒 オブザベーションのバッファ 長 72 更 新 日 時 2010 年 10 月 14 日 木 曜 日 午 後 03 時 36 分 50 秒 削 除 済 みオブザベーション 数 0 保 護 READ/WRITE/ALTER 圧 縮 済 み CHAR データセットタイプ 再 利 用 スペース NO ラベル オブザベーションへのポイント YES データ 表 現 WINDOWS_32 ソート 済 み NO エンコード shift-jis Japanese (SJIS) エンジン/ホスト 関 連 情 報 33
データセットのページサイズ 4096 データセットのページ 数 3 インデックスのページサイズ 4096 インデックスのページ 数 2 データセットの 修 復 数 0 ファイル 名 C:\Users\Hideo\AppData\Local\Temp\SAS Temporary Files\_TD5300\sales2.sas7bdat 作 成 したリリース 9.0101M3 作 成 したホスト WIN_PRO 変 数 と 属 性 の 昇 順 リスト # 変 数 タイプ 長 さ 9 active_year 数 値 8 8 avr_sales 数 値 8 1 dept 文 字 8 2 s01 数 値 8 3 s02 数 値 8 4 s03 数 値 8 5 s04 数 値 8 6 s05 数 値 8 7 tot_sales 数 値 8 インデックスと 属 性 の 昇 順 リスト 一 意 な # インデックス 値 の 数 1 dept 2 ( 主 なデータセットオプション) FIRSTOBS= OBS= SAS データセットを 読 み 取 るときにのみ 有 効 オブザベーションの 読 み 取 り 開 始 番 号 と 終 了 番 号 をそれ ぞれ 指 定 します where=( 条 件 ) ()でくくって SQL の where 条 件 を 指 定 します IN 節 などで 複 数 のアイテムを 指 定 する 場 合 の 区 切 り 文 字 は SQL の 区 切 り 文 字 カンマ(,)でも SAS の 区 切 り 文 字 ブランク 1 個 以 上 のいずれでも 良 い 仕 様 になってい ます 例 ) where=(dept in ("A" "B") or uriage>=1000) keep= 変 数 リスト または drop= 変 数 リスト 作 成 する または 読 み 込 むデータセットの 一 部 の 変 数 のみ 保 存 する または 除 外 することを 指 定 します compress=yes NO 作 成 する SAS データセットの 圧 縮 指 定 です ログに 圧 縮 率 が 表 示 されますが 必 ずしも 容 量 が 減 るとは 限 りません index=(インデクス 変 数 ) password=パスワード これらは SAS データセットをデータベースのように 使 う 場 合 に 便 利 な 機 能 です [PRINT プロシジャ] 34
PROC PRINT data= 入 力 データセット 名 オプション; VAR 変 数 リスト; BY 変 数 リスト; ID 変 数 リスト; SUM 変 数 リスト; RUN; ( 主 なオプション) LABEL ラベルが 定 義 された 変 数 は 変 数 名 の 代 わりに 変 数 ラベルが 表 示 されるようになります この 指 定 を 行 わ ないと たとえ 変 数 ラベルが 定 義 されていても PRINT アウトプット 出 力 に 変 数 ラベルは 使 われない 点 に 注 意 NOOBS 標 準 で 出 力 される 一 番 左 にオブザベーション 番 号 の 表 示 を 抑 制 します (VAR ステートメント) PRINT 表 示 したい 変 数 名 をリストします 全 プロシジャで 共 通 に 使 えるステートメント (BY ステートメント) この 変 数 値 ごとに 別 々に 出 力 されます 全 プロシジャで 共 通 に 使 えるステートメント 前 もって 指 定 された 変 数 の 値 の 大 きさの 順 に 入 力 データセットが 並 んで(ソートされて)いることが 必 要 です (BY ステートメントで 指 定 する 変 数 の 前 につけるオプション) DESCENDING ソートシーケンス(アルファベット 順 )の 逆 順 ( 通 常 降 順 と 呼 びます)にオブザベーションが 並 んでいる 場 合 に 指 定 します 指 定 が 無 いとその 変 数 はアルファベット 順 ( 昇 順 )に 並 んでいるものとみなされます 例 ) BY dept descending sales; dept のアルファベット 順 の 中 で sales が 大 きいものから 小 さいものの 順 にオブザベーションが 並 んでいる ことを 知 らせています (ID ステートメント) 識 別 に 用 いたい 変 数 名 をリストします 指 定 された 変 数 値 が 一 番 左 に 表 示 されるようになり 同 じ ID 値 のオブザベーションは 最 初 のオブザベーションのみ 値 を 表 示 するようになります このステートメントは 多 くのプロシジャで 共 通 に 指 定 できるステートメントです (SUM ステートメント) 数 値 タイプ 変 数 名 をリストできます 全 オブザベーションについての 合 計 値 や(BY ステートメントが 指 定 されていれば) 小 計 値 が 表 示 されるようになります PRINT プロシジャ 独 自 のステートメントです [SORT プロシジャ] オブザベーションを 指 定 の 変 数 値 の 大 きさによって 並 べ 替 えを 行 います PROC SORT data= 入 力 データセット 名 out= 出 力 データセット 名 オプション; 35
BY 変 数 リスト; RUN; ( 主 なオプション) NODUPKEY BY ステートメントの 値 が 同 じオブザベーションは 最 初 のオブザベーションのみ 残 して 残 りを 削 除 します この 指 定 によって 出 力 データセットにおける BY 変 数 値 はユニークになります このオプションを 使 った SORT プロシジャはキー 変 数 の 重 複 が 存 在 するかどうかをチェックする 目 的 で 良 く 使 います (BY ステートメント) 並 べ 替 えを 行 う 変 数 名 をリストします (BY ステートメントで 指 定 する 変 数 の 前 につけるオプション) DESCENDING 後 に 指 定 した 1 個 の 変 数 をソートシーケンス(アルファベット 順 )の 逆 順 ( 通 常 降 順 と 呼 びます)にオブザベ ーションを 並 べ 替 えます 指 定 が 無 いとその 変 数 はアルファベット 順 ( 昇 順 )に 並 べ 変 えます [SORT プロシジャの 重 要 な 注 意 点 ] PROC SORT ステートメントで out= 出 力 データセット 名 を 指 定 しなかった 場 合 data= 入 力 データセット が 並 べ 替 えられたデータセットに 置 き 換 わってしまいます これは 一 般 に 復 元 できませんので 大 変 重 要 な 注 意 点 です (プログラム 1.2-21) SORT と PRINT の 例 proc sort data=sample out=samp2; by sex; proc print data=samp2 label; var height weight age; by sex; id sex; sum age; label height=" 身 長 "; sex 身 長 weight age F 168 59 29 M 175 70 30 180 85 32 178. 40 --- --- M 102 === 131 以 上 で 1.2 データ 読 み 取 り 変 数 作 成 と 横 方 向 の 集 計 処 理 の 学 習 が 終 わりです 2. データ 加 工 2.1 ファイルの 連 結 マージ 更 新 を 含 むプログラミングステートメント 36
~ SET,MERGE,UPDATE ステートメント,DO ループ, 配 列 処 理 SAS は 強 力 なデータ 入 出 力 機 能 とデータ 加 工 機 能 を 持 っています この 節 ではデータ 加 工 機 能 について 学 習 します まず SAS データセットの 読 み 取 りを 行 う 3 つのステートメント SET,MERGE,UPDATE の 使 い 方 を 学 習 します 続 いて 配 列 処 理 を 含 む 主 要 なプログラミングステートメントについて 学 習 します [データセットの 縦 の 連 結 : 1つの SET ステートメント] 既 に 学 習 してきたように SET ステートメントは SAS データセットのオブザベーションを 読 み 取 る 実 行 ステートメントです 1 つの SET ステートメントに 複 数 の SAS データセットを 指 定 するとそれぞれの SAS データセットのオブザベーションを 逐 次 的 に 読 み 取 り DATA ステートメントに 指 定 した 出 力 SAS デ ータセットにオブザベーションを 書 きこむことを 読 み 取 る SAS データセットのオブザベーションが 尽 きるまで 自 動 的 にループ 実 行 します 結 果 的 に SET ステートメントに 指 定 した 複 数 データセットは 縦 方 向 に 連 結 された 形 になります (SET ステートメントの 指 定 方 法 ) 実 行 ステートメント SET SAS データセット 名 (データセットオプション) オプション; SAS データセット 名 複 数 の SAS データセットをブランクで 区 切 って 指 定 できます 複 数 の SAS データセットを 指 定 した 場 合 は 連 続 的 に 指 定 された SAS データセットのオブザベーション を 読 み 取 ります ( 良 く 使 うデータセットオプション) in= 変 数 名 そのデータセットのオブザベーションを 読 み 取 っているときはは 1 そうで 無 いときは 0 の 値 を 持 つ 一 時 的 な 変 数 を 定 義 し 後 に 続 くプログラムで 参 照 できるようにします この 変 数 は 出 力 データセットには 出 力 されません rename=( 変 数 名 = 新 変 数 名 ) 変 数 名 を 変 更 します 複 数 の 変 数 名 を 変 更 する 場 合 は rename=(age=nenrei height=shincho) というように 変 数 名 = 新 変 数 名 のパターンをブランクで 区 切 って 並 べます where=( 条 件 式 ) SQL の where 句 を 記 述 し 読 み 取 るオブザベーションを 条 件 選 択 します 例 ) where=(sex="f" or name in ("suzuki","tanaka")) ( 良 く 使 いオプション) end= 変 数 名 最 後 のオブザベーションを 読 んだ 時 点 で 値 =1 となる 一 時 的 な 変 数 を 定 義 します この 変 数 は 出 力 データ セットには 出 力 されません また point= 指 定 を 行 った 場 合 は 無 効 です nobs= 変 数 名 SET ステートメントに 指 定 された SAS データセットの 合 計 オブザベーション 数 を 値 に 持 つ 一 時 的 な 変 数 うを 定 義 します 37
point= 変 数 名 定 義 された 変 数 の 値 をオブザベーション 番 号 として SAS データセットの 任 意 のオブザベーションを 読 み 取 ることができるようになります このオプションは 1 個 の SAS データセットのみ 指 定 する BY,WHERE ステートメントと 一 緒 に 指 定 できない DATA ステップの 自 動 ループ 実 行 を 終 了 させるために STOP ステートメントがどこかに 必 ず 必 要 など 使 う 上 での 重 要 な 注 意 点 があります (プログラム 2.1-1) 2 つの SAS データセットの 縦 の 連 結 data japan; input ID :$3. name :$10. sex :$1.; cards; 001 fujita M 002 suzuki F 003 takahashi M 004 tanaka M ; data us; input ID :$3. name :$10. age height weight; cards; 101 browne 30 160 51 102 gibson 40 160 48 ; data set1; set japan us; options nocenter; proc print data=set1; (ログ) 213 data set1; 214 set japan us; 215 NOTE: データセット WORK.JAPAN から 4 オブザベーションを 読 み 込 みました NOTE: データセット WORK.US から 2 オブザベーションを 読 み 込 みました NOTE: データセット WORK.SET1 は 6 オブザベーション 6 変 数 です OBS ID name sex age height weight 1 001 fujita M... 2 002 suzuki F... 3 003 takahashi M... 4 004 tanaka M... 5 101 browne 30 160 51 6 102 gibson 40 160 48 SET ステートメントは 指 定 した SAS データセットを 逐 次 的 に 読 み 取 ります 複 数 の SAS データセットに 同 じ 変 数 が 定 義 されていた 場 合 は 最 初 に 定 義 された 変 数 の 型 と 長 さに 設 定 されます いずれかのデータセ ットにのみ 存 在 する 変 数 では 存 在 しなかったデータセットからの 読 み 取 り 値 はすべて 欠 損 値 にセットさ れます (プログラム 2.1-2) IN=データセットオプション data set1; 38
set japan(in=in1) us(in=in2); if in1=1 then country="japan"; else if in2=1 then country="united STATES"; options nocenter; proc print data=set1; (ログ) 218 data set1; 219 set japan(in=in1) us(in=in2); 220 if in1=1 then country="japan"; 221 else if in2=1 then country="united STATES"; 222 NOTE: データセット WORK.JAPAN から 4 オブザベーションを 読 み 込 みました NOTE: データセット WORK.US から 2 オブザベーションを 読 み 込 みました NOTE: データセット WORK.SET1 は 6 オブザベーション 7 変 数 です OBS ID name sex age height weight country 1 001 fujita M... JAPAN 2 002 suzuki F... JAPAN 3 003 takahashi M... JAPAN 4 004 tanaka M... JAPAN 5 101 browne 30 160 51 UNITE 6 102 gibson 40 160 48 UNITE IN 変 数 は 一 時 的 で データセットには 出 力 されない 点 に 注 意 してください また DATA ステップでの 変 数 定 義 ( 型 と 長 さ)は DATA ステップの 中 で 最 初 に 定 義 されたときに 設 定 され ます ここではまず SET ステートメントにより SET された SAS データセットの 全 変 数 が 定 義 され 続 いて IF ステートメントの 中 で 変 数 country が 出 現 しており country="japan"という 割 り 当 てステートメ ントにより 長 さ 5 の 文 字 型 として 定 義 されます したがって 次 の ELSE ステートメントの 変 数 country の 割 り 当 て 値 は 5 文 字 で 切 られてしまっています これを 回 避 するには 最 初 の 割 り 当 てにおいて country="japan "; といったように 後 ろにブランクを 付 加 して 全 体 の 長 さを 指 定 しておく 方 法 と LENGTH ステートメントを 用 いる 方 法 があります (プログラム 2.1-3) LENGTH ステートメント data set1; length country $14; set japan(in=in1) us(in=in2); if in1=1 then country="japan"; else if in2=1 then country="united STATES"; options nocenter; proc print data=set1; OBS country ID name sex age height weight 1 JAPAN 001 fujita M... 2 JAPAN 002 suzuki F... 39
3 JAPAN 003 takahashi M... 4 JAPAN 004 tanaka M... 5 UNITED STATES 101 browne 30 160 51 6 UNITED STATES 102 gibson 40 160 48 (LENGTH ステートメント) 定 義 ステートメント DATA ステップにおける 変 数 の 名 前 と 型 を 明 示 的 に 定 義 します 定 義 ステートメントですが DATA ステ ップでの 位 置 は 重 要 です 定 義 したい 変 数 が LENGTH ステートメントより 前 に SET ステートメントや INPUT ステートメントや 割 り 当 てステートメントなどの 変 数 定 義 を 伴 うステートメントで 既 に 定 義 され ていた 場 合 その 変 数 の LENGTH 指 定 は 無 効 です したがって LENGTH ステートメントは SAS デー タセット 内 の 変 数 の 出 現 順 が 気 にならなければ 常 に DATA ステートメントの 次 に 指 定 すべきです (SAS データセットの 中 の 変 数 は LENGTH ステートメントで 指 定 したものが 先 に 並 ぶことになります ) LENGTH 変 数 名 型 および 長 さ... ; 文 字 型 に 定 義 する 場 合 $を 付 けます (プログラム 2.1-4) SET ステートメントの END=オプション data set1; length country $14; set japan(in=in1) us(in=in2) end=end; if in1=1 then country="japan"; else if in2=1 then country="united STATES"; endflg=end; options nocenter; proc print data=set1; OBS country ID name sex age height weight endflg 1 JAPAN 001 fujita M... 0 2 JAPAN 002 suzuki F... 0 3 JAPAN 003 takahashi M... 0 4 JAPAN 004 tanaka M... 0 5 UNITED STATES 101 browne 30 160 51 0 6 UNITED STATES 102 gibson 40 160 48 1 [ランダムアクセスモード:SET ステートメントの POINT=オプション] (プログラム 2.1-5) SET ステートメント POINT=オプション data rand1; p=2; set set1 point=p; output; p=6; set set1 point=p; output; stop; /* 必 要 */ proc print data=rand1; 40
OBS country ID name sex age height weight endflg 1 JAPAN 002 suzuki F... 0 2 UNITED STATES 102 gibson 40 160 48 1 通 常 の SAS のデータ 読 み 取 りモードはシーケンシャル 読 み 取 り(Sequential Read) モードです SET ステートメントに POINT=オプションを 指 定 すると SET ステートメントに 指 定 した SAS データセットは オブザベーション 番 号 に 基 づくランダムアクセス 方 式 で 読 み 取 りするモードに 変 わります シーケンシャ ル 読 み 取 りモードの 場 合 は 最 後 のオブザベーションを 読 んだ 後 DATA ステップで 実 行 する 最 後 の 実 行 ステートメントを 実 行 後 に DATA ステップを 終 了 させるべきことが SAS にわかります ランダムアクセ スモードになった 場 合 は 最 後 のオブザベーションから 逆 順 にオブザベーションを 読 むといったこともあ り 得 ますので 自 動 的 に DATA ステップを 終 了 するタイミングが SAS にはわかりません そこで ランダ ムアクセスする SAS データセットのみを 入 力 する DATA ステップの 場 合 必 ずどこかに STOP ステートメ ントを 指 定 して 明 示 的 に DATA ステップのループ 実 行 を 終 了 させる 指 定 を 行 う 必 要 があります (STOP ステートメント) 実 行 ステートメント DATA ステップの 実 行 を 終 了 させます DATA ステップは 読 み 取 りデータがない 場 合 は 1 回 だけ 実 行 ある 場 合 は 読 み 取 るデータが 尽 きるまで 繰 り 返 し 実 行 される(ループ 実 行 する)ルールですが STOP ステートメントはこの DATA ステップのループ 実 行 を 明 示 的 に 終 了 させます なお DATA ステップを 完 了 せず 中 止 させるには ABORT ステートメントを 指 定 します この 場 合 DATA ステップはエラーとなり SAS データセットは 作 成 されません また ABORT ステートメントに ABEND オプションを 付 けた ABORT ABEND; を 実 行 すると SAS は 終 了 します (SAS セッションが 終 わります のでここでは 決 して 実 行 しないでください ) (プログラム 2.1-6) SET ステートメント POINT=オプションを 用 いたオブザベーションの 逆 読 み data rand2; do p=nobs to 1 by -1; set set1 point=p nobs=nobs; output; end; stop; /* STOPステートメント 忘 れないこと */ proc print data=rand2; OBS country ID name sex age height weight endflg 1 UNITED STATES 102 gibson 40 160 48 1 2 UNITED STATES 101 browne 30 160 51 0 3 JAPAN 004 tanaka M... 0 4 JAPAN 003 takahashi M... 0 5 JAPAN 002 suzuki F... 0 6 JAPAN 001 fujita M... 0 [ 繰 り 返 し DO ループ] DO インデクス 変 数 名 = 開 始 値 TO 終 了 値 BY 増 分 値 ; 41
( 実 行 ステートメント;) END; TO 終 了 値 および BY 増 分 値 の 部 分 は 指 定 を 省 略 できます DO ステートメントと END ステートメントに 挟 まれた 部 分 の 実 行 ステートメントを 変 数 値 に 開 始 値 を 代 入 して 必 ず 1 回 はループ 実 行 します 各 ループ 実 行 後 変 数 値 + 増 分 値 <= 終 了 値 の 条 件 を 満 たす 場 合 は DO ループを 繰 り 返 し 実 行 します インデクス 変 数 名 = 開 始 値 の 部 分 は カンマで 区 切 って 繰 り 返 し DO ループ 実 行 時 のインデクス 変 数 値 を 個 別 に 指 定 することもできます 例 ) do i=1,3,10; i=1,i=3,i=10 の 値 を 与 えて DO ループを 3 回 繰 り 返 します do i=1,3,5 TO 10 BY 2; i=1,3,5,7,9; と 書 いたのと 同 じ 結 果 になります do i=5,1,4 TO 3 BY -1,2; i=5,1,4,3,2; と 同 じ (プログラム 2.1-7) 繰 り 返 し DO ループの 例 data rand3; do p=5,1,4 TO 3 BY -1,2; set set1 point=p nobs=nobs; output; end; stop; /* STOPステートメント 忘 れないこと */ proc print data=rand3; OBS country ID name sex age height weight endflg 1 UNITED STATES 101 browne 30 160 51 0 2 JAPAN 001 fujita M... 0 3 JAPAN 004 tanaka M... 0 4 JAPAN 003 takahashi M... 0 5 JAPAN 002 suzuki F... 0 [データの 横 の 連 結 (1) 複 数 の SET ステートメントの 指 定 ] (プログラム 2.1-8) 複 数 の SET ステートメントの 指 定 options nodate nonumber nocneter; title "Japan";proc print data=japan; title "US";proc print data=us; data set2; set japan; set us; title "SET2";proc print data=set2; (ログ) NOTE: データセット WORK.JAPAN から 3 オブザベーションを 読 み 込 みました NOTE: データセット WORK.US から 2 オブザベーションを 読 み 込 みました NOTE: データセット WORK.SET2 は 2 オブザベーション 6 変 数 です Japan 42
OBS ID name sex 1 001 fujita M 2 002 suzuki F 3 003 takahashi M 4 004 tanaka M US OBS ID name age height weight 1 101 browne 30 160 51 2 102 gibson 40 160 48 SET2 OBS ID name sex age height weight 1 101 browne M 30 160 51 2 102 gibson F 40 160 48 データセットの 横 の 連 結 で 最 も 簡 単 な 方 法 は 複 数 の SET ステートメントを 用 いることです この 例 では 同 じ 項 目 を 持 つ 2 つの SAS データセット japan と us を 横 につなげる 場 合 です DATA ステップのプログラムデータベクトルを 考 えると 最 初 の SET japan;ステートメントの 実 行 時 に 3 個 の 変 数 (ID,name,sex)の 変 数 が 定 義 され 値 がセットされます そして 次 の SET us; ステートメントで 既 に 定 義 されている 2 個 の 変 数 (ID,name)は 変 数 値 を 上 書 きします そして 3 つの 変 数 age,height,weight は 新 たに 定 義 され 値 がセットされます 変 数 sex は 直 前 のセットされた 値 がそのまま 残 ります このような プロセスで 1 番 目 と 2 番 目 のオブザベーションはいずれのデータセットにも 存 在 しますので DATA ステ ップのループ 実 行 が 行 われ 出 力 されています ログを 見 ると japan データセットは 3 オブザベーション 読 込 み us データセットは 2 件 読 込 んだとあり ます これは DATA ステップの 3 回 目 のループを 開 始 し JAPAN データセットから 3 件 目 のオブザベ ーションを SET することろは 行 われたことを 示 しています ところが 次 の SET us; ステートメントでオ ブザベーションが 無 いことが 分 かり この 時 点 で DATA ステップの 3 回 目 のループは 中 止 されたことを 表 しています 結 果 的 に 複 数 の SET ステートメントによるデータセットの 横 の 連 結 はオブザベーション 数 が 少 ない 方 の 件 数 分 だけ 処 理 され 出 力 されるということに 注 意 [SET ステートメントと BY グループ 処 理 ] SET ステートメントと BY ステートメントを 同 時 に 指 定 した 場 合 入 力 SAS データセットのオブザベー ションの 読 み 取 りは 通 常 と 異 なり BY 変 数 値 の 順 に 行 われます これを BY グループ 処 理 と 呼 びます 同 じ DATA ステップの 中 で 入 力 されるすべての SAS データセットは 事 前 に 同 じ BY ステートメントを 指 定 した PROC SORT を 実 行 済 みでなければなりません (プログラム 2.1-9) SET ステートメントと BY ステートメント 43
proc sort data=japan out=japan2;by name; /* 事 前 にSORTしておく */ proc sort data=us out=us2;by name; /* 事 前 にSORTしておく */ data set_without_by; set japan2 us2; title "Single SET Statement Without By name;"; proc print data=set_without_by; data set_with_by; set japan2 us2; by name; /* BY ステートメント */ title "Single SET Statement With By name;"; proc print data=set_with_by; Single SET Statement Without By name; OBS ID name sex age height weight 1 001 fujita M... 2 002 suzuki F... 3 003 takahashi M... 4 004 tanaka M... 5 101 browne 30 160 51 6 102 gibson 40 160 48 Single SET Statement With By name; OBS ID name sex age height weight 1 101 browne 30 160 51 2 001 fujita M... 3 102 gibson 40 160 48 4 002 suzuki F... 5 003 takahashi M... 6 004 tanaka M... BY ステートメントを 指 定 しない 場 合 は japan2 us2 データセットのオブザベーションを 単 に 順 番 に 読 み 込 んだ 結 果 になっていますが BY ステートメントを 指 定 すると その DATA ステップで 入 力 指 定 した SAS データセットをすべて 同 時 にオープンし BY 変 数 値 の 順 にオブザベーションを 読 みこむモードに 変 わり ます なお BY ステートメントがあると 複 数 の SET ステートメントを 指 定 した 場 合 でも 同 じモードに 入 ってしまい 1 つの SET ステートメントに 複 数 の SAS データセットを 指 定 した 場 合 と 同 じ 結 果 が 得 られ ます [データの 横 の 連 結 (2) MERGE ステートメント] BY ステートメント 無 しの 場 合 に 複 数 の SET ステートメントの 指 定 を 行 うとオブザベーション 数 の 少 ない 方 のオブザベーション 数 の 回 数 しか DATA ステップのループが 実 行 されないため 出 力 されるオブザベーシ ョン 数 は 数 が 少 ない 方 のオブザベーション 数 になります これに 対 して MERGE ステートメントに 複 数 の SAS データセットを 指 定 すると オブザベーションの 多 い 方 に 合 わせて 横 の 連 結 を 行 います (MERGE ステートメント) 実 行 ステートメント 44
MERGE データセット 名 1(データセットオプション) データセット 名 2(データセットオプション)... オ プション; データセット 名 は 最 低 2 個 指 定 します (ただし 1 個 でもエラーにはなりません この 場 合 SET と 同 じ 意 味 になります ) データセットオプションは IN= 変 数 など SET と 同 じものが 指 定 できます オプションは END= 変 数 のみ 指 定 可 能 です (プログラム 2.1-10) MERGE ステートメント data merge1; merge japan us; title; proc print data=merge1; (ログ) NOTE: データセット WORK.JAPAN から 4 オブザベーションを 読 み 込 みました NOTE: データセット WORK.US から 2 オブザベーションを 読 み 込 みました NOTE: データセット WORK.MERGE1 は 4 オブザベーション 6 変 数 です OBS ID name sex age height weight 1 101 Browne M 30 160 51 2 102 Gibson F 40 160 48 3 003 takahashi M... 4 004 tanaka M... MERGE ステートメントは 指 定 した SAS データセットを 同 時 にオープンし 同 じオブザベーション 番 号 同 士 のオブザベーションを 横 に 連 結 します (プログラム 2.1-8)と 比 較 すると ログでは JAPAN データセ ットを 4 件 US データセットを 2 件 読 んでおり いずれも 全 件 読 んでいることがわかります アウトプ ットを 比 較 すると OBS1 と OBS2 は 全 変 数 の 値 が 同 じになっています そして OBS3 と OBS4 が 出 力 されており いずれも JAPAN データセットからのオブザベーション 値 が 入 っています [マッチマージ: MERGE ステートメントと BY グループ 処 理 ] BY ステートメントを MERGE ステートメントと 一 緒 に 用 いると 同 じオブザベーション 番 号 ではなく BY 変 数 値 の 値 が 同 じオブザベーションを 横 に 揃 えて 連 結 しようとするモードに 変 わります 一 方 の SAS データセットの BY 変 数 値 がユニークな 顧 客 番 号 とその 顧 客 属 性 情 報 を 格 納 したデータセッ ト もう 一 方 は 顧 客 番 号 と 取 引 情 報 を 格 納 したデータセットのようなとき 取 引 情 報 に 顧 客 番 号 で 紐 づけ られた 顧 客 属 性 項 目 を 付 加 したい 場 合 などに 大 変 良 く 使 われる 指 定 です (プログラム 2.1-11) マッチマージの 例 title "USデータセット"; proc print data=us; data trans; input ID :$3. yyyymmdd :$8. itemno :$3. sales; cards; 101 20101001 A01 256 102 20101003 B02 600 103 20101004 C01 123 45
102 20101005 B03 850 101 20101006 A03 45 ; proc sort data=us;by ID; proc sort data=trans;by ID; data match_merged; merge us trans; by ID; title "マッチマージの 結 果 "; proc print data=match_merged; (ログ) NOTE: データセット WORK.US から 2 オブザベーションを 読 み 込 みました NOTE: データセット WORK.TRANS から 5 オブザベーションを 読 み 込 みました NOTE: データセット WORK.MATCH_MERGED は 5 オブザベーション 8 変 数 です USデータセット OBS ID name age height weight 1 101 browne 30 160 51 2 102 gibson 40 160 48 マッチマージの 結 果 OBS ID name age height weight yyyymmdd itemno sales 1 101 browne 30 160 51 20101001 A01 256 2 101 browne 30 160 51 20101006 A03 45 3 102 gibson 40 160 48 20101003 B02 600 4 102 gibson 40 160 48 20101005 B03 850 5 103... 20101004 C01 123 [n 対 mのマージ] マッチマージが 片 方 のデータセットの BY 変 数 値 がユニーク もう 片 方 はユニークで 無 い 場 合 (1 対 nと 呼 ぶ)の 同 じ BY 変 数 値 のオブザベーションの 横 の 連 結 を 意 味 し 結 果 は 明 らかになるのに 対 して 両 方 のデータセットの BY 変 数 値 がユニークで 無 い 場 合 (n 対 mと 呼 ぶ)はどのようになるでしょう? (プログラム 2.1-12) n 対 m のマージの 例 data cardinfo; input ID :$3. cardnum :$9.; cards; 101 CARD101_1 102 CARD102_1 102 CARD102_2 102 CARD102_3 ; data trans; input ID :$3. yyyymmdd :$8. itemno :$3. sales; cards; 101 20101001 A01 256 101 20101006 A03 45 46
102 20101003 B02 600 102 20101005 B03 850 ; data merge_n_m; merge cardinfo trans; by ID; title "n 対 mのマージ"; proc print data=merge_n_m; (ログ) NOTE: MERGE ステートメントに BY 値 を 繰 り 返 すデータセットが 複 数 あります NOTE: データセット WORK.CARDINFO から 4 オブザベーションを 読 み 込 みました NOTE: データセット WORK.TRANS から 4 オブザベーションを 読 み 込 みました NOTE: データセット WORK.MERGE_N_M は 5 オブザベーション 5 変 数 です ログに MERGE ステートメントに BY 値 を 繰 り 返 すデータセットが 複 数 あります というメッセージが 出 ることに 注 目 n 対 mのマージ OBS ID cardnum yyyymmdd itemno sales 1 101 CARD101_1 20101001 A01 256 2 101 CARD101_1 20101006 A03 45 3 102 CARD102_1 20101003 B02 600 4 102 CARD102_2 20101005 B03 850 5 102 CARD102_3 20101005 B03 850 OBS=5 のオブザベーションに 注 目 TRANS データセットには ID="102"は 2 件 しかありませんが CARDINFO データセットには ID="102"は 3 件 あります これが n 対 m のマージになっています 多 い 方 の 3 件 がアウトプットされますが 3 件 目 のオブザベーションの TRANS データセットからの 変 数 yyyymmdd,itemno,sales の 値 は 2 件 目 の 値 がコピーされています SAS では MERGE ステートメントに BY 値 を 指 定 した 場 合 このような 特 別 な 値 保 持 モード になるのがデフォルトです [n 対 mのマージでデータ 値 が 存 在 しない 場 合 は 欠 損 値 にセットする 方 法 ] 上 記 の 結 果 は 一 見 不 自 然 ( 理 不 尽 )にも 思 えますが 1 対 n のマッチマージを 考 えると オブザベーシ ョン 数 が 足 りない 部 分 のマージ 後 の 変 数 値 は マージできた 最 後 のオブザベーションの 変 数 値 をそのまま コピーする という 仕 方 によってマッチマージの 結 果 が 得 られているわけで 同 じ 理 屈 を n 対 m でも 実 行 しているのです 足 りない 部 分 のオブザベーションの 変 数 値 を 欠 損 にするには 以 下 のように IN=データセットオプション を 用 いて MERGE ステートメント 実 行 の 前 に IN 変 数 値 =0 に 設 定 します (プログラム 2.1-13) n 対 m のマージの 例 で 足 りないオブザベーション 側 の 変 数 値 を 制 御 する data merge_n_m; trans=0; /* 制 御 したいデータセットのIN 変 数 をリセット */ merge cardinfo trans(in=trans); /* 制 御 したい 変 数 の 入 っているデータセットにIN 変 数 を 定 義 */ by ID; 47
if trans=0 then do; /* IN 変 数 が0 すなはち 読 み 取 りデータが 無 い 場 合 のDO 処 理 を 開 始 */ yyyymmdd=.;itemno=""; /* 変 数 値 をセット */ end; /* DO 処 理 の 終 了 */ title "n 対 mのマージ"; proc print data=merge_n_m; n 対 mのマージ OBS ID cardnum yyyymmdd itemno sales 1 101 CARD101_1 20101001 A01 256 2 101 CARD101_1 20101006 A03 45 3 102 CARD102_1 20101003 B02 600 4 102 CARD102_2 20101005 B03 850 5 102 CARD102_3. 850 DATA ステートメントの 次 の 最 初 の 割 り 当 てステートメント trans=0; は 必 要 です MERGE ステートメ ントの 特 別 な 値 保 持 モード は DATA ステップのループ 実 行 の 間 ずっと 有 効 になるからです DATA ス テップの 各 ループ 処 理 ごとにこの 値 保 持 モードを 常 にリセットするために 最 初 に 指 定 する 必 要 があります なお 両 方 の 入 力 データセットについてこれを 行 うときは IN=データセットオプションを 両 方 につけて 冒 頭 で 同 じように 割 り 当 てステートメントを 書 いて if ~end 処 理 を 同 じように 書 き 加 えてください 参 考 として merge ステートメントと by ステートメントを 用 いたデータの 横 の 連 結 指 定 において in=デ ータセットオプションの 指 定 や 値 保 持 モードのリセットを 指 定 した 場 合 の 結 果 の 差 異 を[ 別 表 8] に 例 示 し ました [データセットの 値 の 更 新 UPDATE ステートメント] SAS データセットを 更 新 するには UPDATE ステートメント もしくは MODIFY ステートメントを 使 いま す MODIFY ステートメントは 直 接 更 新 したいデータセットのデータを 修 正 してしまうもので ここでは 取 り 扱 いません UPDATE ステートメントは ある SAS データセット(Master)に 対 する 修 正 情 報 を 格 納 した SAS データセット(Transaction)を 用 意 し 別 のデータセットに 更 新 された SAS データセットを 作 成 する 方 法 を 実 行 するものです (プログラム 2.1-14) data japan; input ID :$3. name :$10. sex $:1.; cards; 001 fujita M 002 suzuki F 003 takahashi M 004 tanaka M ; data modinfo; input ID :$3. name :$10. sex $:1.; cards; 003 takashi. 004. F ; UPDATE ステートメントによるデータセットの 更 新 48
data japan2; update japan modinfo; by ID; title; proc print data=japan2; OBS ID name sex 1 001 fujita M 2 002 suzuki F 3 003 takashi M 4 004 tanaka F (UPDATE ステートメント) 実 行 ステートメント UPDATE マスターデータセット 名 トランザクションデータセット 名 オプション; マスターデータセットは 更 新 前 の SAS データセットを 指 定 します BY ステートメントを 指 定 し マスターデータセットの BY 変 数 値 はユニークでなければなりません トランザクションデータセットの BY 値 はユニークでなくてかまいません 更 新 情 報 を 以 下 のように 入 力 しておきます 更 新 したい 項 目 はマスターと 同 じ 変 数 名 を 持 たせます BY 変 数 値 をユニークキーとして 更 新 したいデータ 値 は 更 新 情 報 更 新 しないデータには 欠 損 値 をセッ トしておきます マスターに 存 在 しない BY 値 は 新 規 オブザベーションとして 追 加 されます 以 上 でファイルの 連 結 マージ 更 新 のテーマは 終 了 です [DO ループ 処 理 ] 繰 り 返 し DO ループについては 既 に 学 びましたので その 他 の DO ループ 処 理 について 学 びます (DO WHILE ステートメント) 実 行 ステートメント DO WHILE ( 条 件 式 ); ( 実 行 ステートメント;) END; DO WHILE ステートメントは DO ループの 開 始 前 に 条 件 判 断 を 行 い 条 件 を 満 たす 場 合 DO ループを 実 行 します 繰 り 返 し DO ループと DO UNTIL ループが 1 度 は 必 ず DO ループを 実 行 するのに 対 して DO WHILE ループは 一 度 も 実 行 されない 場 合 もあり 得 ます (プログラム 2.1-15) data _null_; i=10; 49
do while (i>=1); put i=; i=i-1; end; (ログ) 1023 data a; 1024 i=10; 1025 do while (i>=1); 1026 put i=; 1027 i=i-1; 1028 end; 1029 i=10 i=9 i=8 i=7 i=6 i=5 i=4 i=3 i=2 i=1 (DO UNTIL ステートメント) 実 行 ステートメント DO UNTIL ( 条 件 式 ); ( 実 行 ステートメント;) END; DO UNTIL ステートメントは DO ループの 終 了 後 に 条 件 判 断 を 行 い 条 件 を 満 たさない 場 合 DO ループを 再 度 実 行 します 1 度 は 必 ず DO ループを 実 行 します (プログラム 2.1-16) data _null_; i=10; do until (i>=1); put i=; i=i-1; end; (ログ) 1030 data _null_; 1031 i=10; 1032 do until (i>=1); 1033 put i=; 1034 i=i-1; 1035 end; 1036 50
i=10 [ 配 列 処 理 ] DATA ステップの 複 数 の 変 数 をまとめて 配 列 として 配 列 名 で 宣 言 しておけば 同 じ 処 理 を 複 数 の 変 数 に 対 して 行 いたい 場 合 変 数 ごとに 処 理 を 書 かなくて 済 むようになります SAS の 配 列 はそのような 目 的 で 使 うものと 考 えてください (ARRAY ステートメント) 宣 言 ステートメント ARRAY 配 列 名 { 要 素 数 } 型 と 長 さ 変 数 名 リスト; 例 ) array x{100} x1-x100; array var {*} TOKYO OSAKA NAGOYA; 要 素 数 の 部 分 は 要 素 変 数 の 数 を 書 いてもかまいませんが 通 常 省 略 値 * を 書 けば 十 分 です SAS が カウントします 要 素 数 の 指 定 部 分 は インデクス 開 始 値 : 終 了 値 x{0:99} 多 次 元 配 列 指 定 x{4,25} といった 指 定 も 可 能 です いずれも 要 素 数 は 100 になりますが 配 列 要 素 を 参 照 するインデクス 番 号 が 異 なることになりま す 例 えば 26 番 目 の 要 素 変 数 を 参 照 するには x{100} 配 列 定 義 の 場 合 は x{26} x{0:99} 配 列 定 義 の 場 合 は x{25} x{4,25} 配 列 定 義 の 場 合 は x{2,1}と 参 照 することになります 配 列 名 は SAS の 名 前 付 けルールに 従 います ( 最 大 32 文 字 ) 文 字 変 数 は 文 字 変 数 同 士 数 値 変 数 は 数 値 変 数 同 士 しか 同 じ 配 列 名 で 定 義 できません 既 に 入 力 データセットに 存 在 する 変 数 やあらかじめ LENGTH ステートメントなどで 定 義 済 みの 変 数 を 配 列 定 義 する 場 合 は 矛 盾 する 型 と 長 さを 指 定 してはいけません 配 列 名 から 各 変 数 の 参 照 方 法 は 以 下 の 通 りです 配 列 名 { 要 素 番 号 } 例 ) x{5}=100; 上 記 array 定 義 の 場 合 x5=100; と 書 くのと 同 じ total=x{1}+x{2}; 同 様 に total=x1+x2; sumsales=var{2}+var{3} 同 様 に sumsales=osaka+nagoya; (プログラム 2.1-17) 配 列 なしのプログラミング data array_nasi; set sales; s01=s01*10; s02=s02*10; s03=s03*10; s04=s04*10; s05=s05*10; tot_sales=tot_sales*10; avr_sales=avr_sales*10; proc print data=array_nasi; 51
(ログ) 1218 data array_nasi; 1219 set sales; 1220 s01=s01*10; 1221 s02=s02*10; 1222 s03=s03*10; 1223 s04=s04*10; 1224 s05=s05*10; 1225 tot_sales=tot_sales*10; 1226 avr_sales=avr_sales*10; 1227 NOTE: 欠 損 値 を 含 んだ 計 算 により 以 下 の 箇 所 で 欠 損 値 が 生 成 されました ( 回 数 )( 行 : カラム ) 1 1223:10 1 1224:10 NOTE: データセット WORK.SALES から 3 オブザベーションを 読 み 込 みました NOTE: データセット WORK.ARRAY_NASI は 3 オブザベーション 9 変 数 です tot_ avr_ active_ OBS dept s01 s02 s03 s04 s05 sales sales year 1 A 1250 1000 1810 2010 2250 8320 1664 5 2 B 800 1150 3000 2620 1930 9500 1900 5 3 C 100 110 120.. 330 110 3 ログに 欠 損 値 との 演 算 結 果 が 欠 損 値 になった 箇 所 と DATA ステップループ 回 数 が 表 示 されている 点 に 注 意 (プログラム 2.1-18) 配 列 を 用 いたプログラミング data array_ari; set sales; array s {*} s01-s05 tot_sales avr_sales; do i=1 to dim(s); s{i}=s{i}*10; end; proc print data=array_ari; tot_ avr_ active_ OBS dept s01 s02 s03 s04 s05 sales sales year i 1 A 1250 1000 1810 2010 2250 8320 1664 5 8 2 B 800 1150 3000 2620 1930 9500 1900 5 8 3 C 100 110 120.. 330 110 3 8 do i=1 to dim(s); の dim(s) は 配 列 の 要 素 数 を 返 す 関 数 です この DO ループのインデクス 変 数 i も drop しないと 出 力 データセットに 含 まれてしまう 点 に 注 意 [RETAIN ステートメントと 合 計 ステートメント] ここで DATA ステップでオブザベーションの 縦 方 向 の 集 計 などを 行 う 場 合 に 用 いなければならなくなる RETAIN ステートメントと 合 計 ステートメントについて 学 習 しておきます (RETAIN ステートメント) 宣 言 ステートメント 52
DATA ステップのループ 実 行 時 は MERGE ステートメントの BY 処 理 が 行 われるときのような 特 別 な 場 合 以 外 基 本 的 にデータベクトルの 値 はリセットされ 欠 損 値 がセットされます それでは DATA ステッ プで 複 数 のオブザベーションにわたる 計 算 を 行 うことができません そこで DATA ステップの 新 しいル ープを 実 行 しても 前 の DATA ステップループ 時 の 最 後 の 値 を 保 持 するために RETAIN ステートメントが 用 意 されています 指 定 は 非 常 に 簡 単 で RETAIN 変 数 名 初 期 値 ; です 初 期 値 は 指 定 しなくてもかまいません その 場 合 は 最 初 の DATA ステップのループ 開 始 時 は 欠 損 値 にセットされます なお 変 数 名 も 省 略 し RETAIN;と 書 くとその DATA ステップに 登 場 する 全 変 数 が RETAIN されます 例 ) retain x y 1 z; retain a "ABC" b; x と y は 初 期 値 1,z は 欠 損 値 にセット a は"ABC",b は""(" ")に 初 期 値 セット (プログラム 2.1-19) RETAIN ステートメント data retain1; array sum {*} 8 sum1-sum5; retain sum1-sum5 0; set sales end=end; array s {*} s01-s05; do i=1 to 5; sum{i}=sum{i}+s{i}; end; proc print data=retain1; tot_ avr_ active_ OBS sum1 sum2 sum3 sum4 sum5 dept s01 s02 s03 s04 s05 sales sales year i 1 125 100 181 201 225 A 125 100 181 201 225 832 166.4 5 6 2 205 215 481 463 418 B 80 115 300 262 193 950 190.0 5 6 3 215 226 493.. C 10 11 12.. 33 11.0 3 RETAIN ステートメントをコメントにして 実 行 してみてください 欠 損 値 との 足 し 算 で 結 果 が sum4 sum5 は 欠 損 値 となってしまいましたが 欠 損 を 足 しても 欠 損 をゼロ とみなして 足 しこみ 計 算 ( 累 積 )を 行 いたい 場 合 があります そこで 合 計 ステートメントが 登 場 します ( 合 計 ステートメント) 実 行 ステートメント 変 数 名 + 式 ; 一 寸 変 わっていますが +がキーワードです 変 数 名 に 該 当 する 変 数 が 合 計 値 を 取 る 変 数 名 として 認 識 さ れます 例 ) 53
a+1; a+b; sum+x{i}; DATA ステップのループ 実 行 ごとに 変 数 a に 1 を 足 した 値 を 新 たな a の 値 にします a+1; が a=a+1; と 異 なるのは a が RETAIN されることです a+b; が a=a+b; と 異 なるのは a が RETAIN されることと b の 値 が 欠 損 であっても 0 とみなして 足 し こみを 行 うことです 合 計 ステートメントに 指 定 した 変 数 は RETAIN ステートメントに 指 定 しなくても RETAIN されます 定 数 を 差 し 引 きしたい 場 合 は+はキーワードなので +(-1) のように 指 定 します (プログラム 2.1-20) 合 計 ステートメント data retain2; array sum {*} 8 sum1-sum5; set sales end=end; array s {*} s01-s05; do i=1 to 5; sum{i}+s{i}; end; proc print data=retain2; tot_ avr_ active_ OBS sum1 sum2 sum3 sum4 sum5 dept s01 s02 s03 s04 s05 sales sales year i 1 125 100 181 201 225 A 125 100 181 201 225 832 166.4 5 6 2 205 215 481 463 418 B 80 115 300 262 193 950 190.0 5 6 3 215 226 493 463 418 C 10 11 12.. 33 11.0 3 54
2.2 日 付 処 理 関 数 フォーマットの 利 用 と DATA ステップを 用 いたレポーティング ~ 日 付 フォーマット 日 付 インフォーマット 日 付 関 数 FORMAT プロシジャ BY グループ 処 理 PUT ステートメント ここでは SAS における 時 間 の 取 り 扱 いと DATA ステップを 用 いたレポーティングについて 学 習 します SAS では 日 時 の 取 り 扱 いは 1960 年 1 月 1 日 を 起 点 とする 経 過 日 数 を 値 とする SAS 日 付 値 1960 年 1 月 1 日 午 前 0 時 0 分 0 秒 を 起 点 とする 経 過 秒 数 を 値 とする SAS 日 時 値 そして 午 前 0 時 0 分 0 秒 を 起 点 とする 経 過 秒 数 を 値 とする SAS 時 間 値 という 3 通 りの 基 本 的 時 間 概 念 があります SAS では 時 間 タイプといった 特 別 なタイプの 変 数 はありません すべて 通 常 の 数 値 タイプの 変 数 です 変 数 値 が 1960 年 1 月 1 日 からの 経 過 日 数 を 表 すものとみなせば SAS 日 付 値 になり 経 過 秒 数 を 表 すものとみなせば SAS 日 時 値 になるという 仕 組 みです 外 部 データ 上 の 日 付 や 時 間 を 表 すさまざまな 表 現 形 式 のデータを SAS 日 付 値 として 読 み 込 むには INPUT ステートメントのフォーマット 入 力 に 日 付 や 時 間 に 関 するインフォーマットを 用 います 逆 に SAS 日 付 値 や SAS 日 時 値 を 年 月 日 表 示 などの 表 現 形 式 で 外 部 データやアウトプットとして 書 き 出 すにはフォーマ ットを 用 います SAS 日 付 値 を 通 常 の 年 月 日 表 現 の 文 字 値 に 変 換 する 逆 に 年 月 日 の 表 現 形 式 で 記 述 された 文 字 変 数 値 か ら SAS 日 付 値 に 変 換 する PUT 関 数 や INPUT 関 数 があります また 顧 客 の 誕 生 日 から 現 在 の 年 齢 を 計 算 し たり 最 初 に 顧 客 になってからの 経 過 日 数 を 計 算 することができる INTCK 関 数 任 意 の 時 間 経 過 後 の SAS 日 付 値 を 算 出 する INTNX 関 数 などがあります 時 間 に 関 する 学 習 の 後 は DATA ステップで 集 計 レポートを 作 成 するプログラミングを 学 習 します 一 般 的 な 営 業 所 別 部 門 別 販 売 取 引 データセットを 入 力 し 営 業 所 別 部 門 別 売 上 合 計 を 計 算 して 集 計 表 を 作 成 するようなことが 行 われます 部 門 別 集 計 を 行 うとき 活 躍 するのは BY グループ 処 理 です BY グループ 処 理 については SET,MERGE,UPDATE ステートメントにおける BY グループ 処 理 が 登 場 しましたが こ こではコントロールブレイクと 呼 ばれる BY 変 数 値 の 変 化 のタイミングをとらえる FIRST.BY 変 数, LAST.BY 変 数 という 特 殊 な 機 能 について 理 解 します また DATA ステップを 用 いたレポーティングには PUT ス テートメントが 活 躍 します [ 日 付 値 日 時 値 時 間 値 ] まず それぞれ 定 数 で 与 える 方 法 と 与 えらた 値 の 内 部 値 (SAS 変 数 値 )を 確 認 します (プログラム 2.2-1) SAS 日 付 値 日 時 値 時 間 値 data _null_; date1="01jan1960"d; date2="31dec60"d; date3="17dec10"d; put date1= date2= date3=; datetime1="01jan1960:00:00:00"dt; datetime2="31dec60:23:59:59"dt; put datetime1= datetime2=; time1="00:00:00"t; time2="24:00:00"t; time3="39:15:30.9"t; 55
put time1= time2= time3=; date4="31mar20"d; put date4=; (ログ) date1=0 date2=365 date3=18613 datetime1=0 datetime2=31622399 time1=0 time2=86400 time3=141330.9 date4=-14520 日 付 値 は""D, 日 時 値 は ""DT, 時 間 値 は""T という 特 別 な 表 現 で 定 数 を 与 えます ""の 中 は 日 付 は ddmmmyy または ddmmmyyyy ただし mmm の 部 分 は 英 語 の 月 名 を 表 す 3 文 字 が 入 り ます 時 間 部 分 は hh:mm:ss.s の 形 式 で 与 えます 日 時 値 の 場 合 日 付 と 時 間 部 分 の 区 切 りにも":"を 付 けます "ddmmmyy" は DATE7 フォーマット "ddmmmyyyy" は DATE9 フォーマットと 呼 ばれます DATE7 フォーマットのときは 西 暦 が 下 2 桁 で 表 現 されていますので 19xx なのか 20xx のいずれを 表 している のかが 問 題 になります ( 2000 年 問 題 ) SAS ではこの 問 題 に 対 して yearcutoff=というオプションで 対 応 しており 現 在 のオプション 設 定 値 は 次 の 指 定 を 実 行 するとログに 表 示 されます (プログラム 2.2-2) SAS 設 定 オプション YEARCUTOFF=の 確 認 proc options; (ログ) YEARCUTOFF=1920 SAS 日 付 処 理 の 100 年 単 位 の 基 準 年 を 指 定 します これは 2 桁 の 西 暦 年 表 示 は 1920 年 から 2019 年 の 間 にあるものとみなすという 意 味 です したがって 2020 年 を 表 すつもりで date="31mar20"d; と 書 いても 今 の YEARCUTOFF 設 定 では SAS は 1920 年 3 月 31 日 と 認 識 します そのため 上 記 の 例 での SAS 変 数 値 date4 の 値 は 起 点 の 1960 年 から 40 年 前 の- 14520 という 値 になります なお 1960 年 は 閏 年 なので 366 日 あったことに 注 意 [ 日 付 フォーマット] SAS 日 付 値 を 経 過 日 数 で 表 示 しても 何 のことかわかりません これを 年 月 日 表 示 してみましょう SAS 変 数 値 を 特 定 の 編 集 形 式 で 書 き 出 すにはフォーマットを 使 います [ 別 表 6]にある SAS 日 付 値 日 時 値 時 間 値 ごとに 使 えるフォーマットの 一 覧 を 掲 載 してありますので 参 考 にしてください (プログラム 2.2-3) FORMAT の 指 定 data _null_; date="17dec10"d; put date yymmdd. +1 date yymmddn8. +1 date yymmdds10. +1 date yymmdd4.; datetime="31dec60:23:59:59"dt; put datetime datetime. +1 datetime dtdate.; time="39:15:30.9"t; put time time. time timeampm.; 56
(ログ) 10-12-17 20101217 2010/12/17 1012 31DEC60:23:59:59 31DEC60 39:15:31 3:15:31 PM [PUT 関 数 ] PUT 関 数 は PUT( 変 数 名,フォーマット) という 文 法 で 1 番 目 の 引 数 の 変 数 の 値 を 2 番 目 の 引 数 に 指 定 したフォーマットで 編 集 した 値 を 返 します SAS 日 付 値 を 日 付 フォーマットで 書 き 出 した 値 に 変 換 することが PUT 関 数 で 可 能 です なお PUT 関 数 の 結 果 は 必 ず 文 字 タイプになります 例 ) x=1234567; date=put(x,comma12.); date="1,234,567" になります (プログラム 2.2-4) PUT 関 数 data _null_; date="17dec10"d; date2=put(date,yymmdds10.); datetime="31dec60:23:59:59"dt; datetime2=put(datetime,datetime.); time="39:15:30.9"t; time2=put(time,timeampm.); put date2 / datetime2 / time2; (ログ) 2010/12/17 31DEC60:23:59:59 3:15:31 PM [インフォーマットと INPUT 関 数 ] フォーマットに 対 してインフォーマットがあり PUT 関 数 に 対 して INPUT 関 数 があります インフォーマットは 外 部 データの 編 集 形 式 に 合 わせて SAS 変 数 に 読 み 取 るときに 使 います (プログラム 2.2-5) INFORMAT を 使 い 日 付 を 表 すデータを SAS 日 付 値 として 読 み 込 む data _null_; input date :yymmdd8.; put date " " +1 date date9.; cards; 19600101 20101018 ; (ログ) 57
0 01JAN1960 18553 18OCT2010 INPUT 関 数 は INPUT( 変 数 名,インフォーマット) という 文 法 で 1 番 目 の 引 数 の 変 数 の 値 を 2 番 目 の 引 数 に 指 定 したインフォーマットで 読 み 込 んだときの SAS 変 数 値 の 値 を 返 します この 関 数 の 結 果 はイン フォーマットが 文 字 型 なら 文 字 タイプ 数 値 型 なら 数 値 タイプになります これは INPUT ステートメン トでインフォーマットを 指 定 した 場 合 と 同 じです (プログラム 2.2-6) INPUT 関 数 data _null_; input date $ 1-8; sasdate_value=input(date,yymmdd8.); put date " " +1 sasdate_value; cards; 19600101 20101018 ; (ログ) 19600101 0 20101018 18553 [ 経 過 時 間 の 計 算 など] INTCK 関 数 を 使 えば 2 つの SAS 日 付 値 日 時 値 時 間 値 の 経 過 期 間 を 計 算 することができます ただ し 年 齢 計 算 には 向 きません 日 付 値 などから 年 月 日 などを 取 り 出 す 関 数 などについてもここで 学 習 します (プログラム 2.2-7) INTCK 関 数 data sample; input ID name :$10. birth :yymmdd8.; cards; 001 fujita 19580409 002 suzuki 19850131 003 takahashi 19921201 004 tanaka 20091231 ; data intck; set sample; today=today(); keikayear=intck("year",birth,today); keikamonth=intck("month",birth,today); keikaday=intck("day",birth,today); keikaday2=today-birth; proc print data=intck; format birth today yymmdds10.; OBS ID name birth today keikayear keikamonth keikaday keikaday2 58
1 1 fujita 1958/04/09 2010/10/17 52 630 19184 19184 2 2 suzuki 1985/01/31 2010/10/17 25 309 9390 9390 3 3 takahashi 1992/12/01 2010/10/17 18 214 6529 6529 4 4 tanaka 2009/12/31 2010/10/17 1 10 290 290 (INTCK 関 数 の 指 定 方 法 ) INTCK(" 時 間 単 位 ", 開 始 値, 終 了 値 ) " 時 間 単 位 "には year, qtr, month, week, day, hour, minute, second が 指 定 できます 開 始 値 終 了 値 は SAS 日 付 値 などとみなされます 同 じ 仲 間 の 関 数 に 今 から 3 年 後 の 日 付 を 計 算 するといった 用 途 に 用 い る INTNX 関 数 があります INTNX(" 時 間 単 位 ", 開 始 値, 増 分 ) 例 ) 3month_after=intnx("month",today(),3); INTCK 関 数 を 使 った 年 数 計 算 は 開 始 値 終 了 値 ともにその 時 間 単 位 のスタート 時 点 ( 時 間 単 位 が" 年 "な ら 開 始 値 終 了 値 とも 月 日 部 分 は 1 月 1 日 )とみなして 計 算 します したがって 12 月 31 日 の 誕 生 日 と 翌 日 の 10 月 17 日 を INTCK 関 数 で 経 過 年 数 を 計 算 すると 1 が 返 ってくるわけです [ 年 齢 計 算 ] というわけで INTCK 関 数 は 使 わずに 年 齢 計 算 を 行 います (プログラム 2.2-8) 年 齢 計 算 data nenrei; set sample; /* 普 通 の 年 齢 計 算 方 法 */ today=today(); by=year(birth); bm=month(birth); bd=day(birth); /* 年 月 日 とそれぞれ 取 り 出 す */ ty=year(today); tm=month(today); td=day(today); /* 年 月 日 とそれぞれ 取 り 出 す */ nenrei1=ty-by-(bm*100+bd>tm*100+td); /* 年 の 差 をとる 誕 生 日 が 基 準 日 で 未 到 来 ( 大 きい)なら 1を 引 く */ /* もう1つの 簡 単 な 方 法 */ nenrei2=int(input(put(today,yymmddn8.),8.4)-input(put(birth,yymmddn8.),8.4)); proc print data=nenrei; format birth today yymmdds10.; OBS ID name birth today by bm bd ty tm td nenrei1 nenrei2 1 1 fujita 1958/04/09 2010/10/17 1958 4 9 2010 10 17 52 52 2 2 suzuki 1985/01/31 2010/10/17 1985 1 31 2010 10 17 25 25 3 3 takahashi 1992/12/01 2010/10/17 1992 12 1 2010 10 17 17 17 4 4 tanaka 2009/12/31 2010/10/17 2009 12 31 2010 10 17 0 0 [ 数 値 - 文 字 変 換 ] 59
PUT 関 数 を 使 えば 数 値 変 数 値 を 別 の 文 字 タイプの 変 数 に 持 たせることができます (プログラム 2.2-9) 数 値 - 文 字 変 換 options nocenter; data a; input x; /* 数 値 タイプとして 読 む */ length c1 $8; /* 文 字 タイプに 定 義 */ c1=x; /* 自 動 変 換 */ c2=put(x,5.); /* フォーマットで 文 字 変 数 の 長 さを 指 定 します */ c3=put(x,6.2); /* フォーマットで 文 字 変 数 の 長 さを 指 定 します */ c4=put(x,best12.); cards; 12345 123.45 1.23456e10 ; proc print data=a; proc contents data=a; (ログ) 490 options nocenter; 491 data a; 492 input x; /* 数 値 タイプとして 読 む */ 493 length c1 $8; /* 文 字 タイプに 定 義 */ 494 c1=x; /* 自 動 変 換 */ 495 c2=put(x,5.); /* フォーマットで 文 字 変 数 の 長 さを 指 定 します */ 496 c3=put(x,6.2); /* フォーマットで 文 字 変 数 の 長 さを 指 定 します */ 497 c4=put(x,best12.); 498 cards; NOTE: 以 下 の 箇 所 で 数 値 を 文 字 値 に 変 換 しました ( 行 : カラム ) 494:6 NOTE: データセット WORK.A は 3 オブザベーション 5 変 数 です NOTE: 数 値 をプリントするには 小 さすぎる W.D 出 力 形 式 がありました "BEST" 出 力 形 式 によって 小 数 点 がシフトされる 場 合 があります OBS x c1 c2 c3 c4 1 12345.00 12345 12345 12345 12345 2 123.45 123.45 123 123.45 123.45 3 12345600000.00 1.235E10 12E9 123E8 12345600000 変 数 と 属 性 の 昇 順 リスト # 変 数 タイプ 長 さ 2 c1 文 字 8 3 c2 文 字 5 4 c3 文 字 6 5 c4 文 字 12 1 x 数 値 8 文 字 タイプ 定 義 された 変 数 に 数 値 タイプ 変 数 を 割 り 当 てると 文 字 変 数 に 自 動 変 換 されることに 注 意 60
また 文 字 フォーマット w. で 小 数 点 以 下 の 桁 数 を 指 定 する w.d の d は 指 定 しても 無 視 されます [ 文 字 - 数 値 変 換 ] 逆 に PUT 関 数 と INPUT 関 数 を 使 えば 数 字 が 入 っている 文 字 変 数 の 値 を 別 の 数 値 変 数 に 持 たせること ができます (プログラム 2.2-10) 文 字 - 数 値 変 換 options nocenter; data a; input c :$10.; /* 文 字 タイプとして 読 む */ length x1 8; /* 数 値 タイプに 定 義 */ x1=c; /* 自 動 変 換 */ x2=input(c,5.); /* フォーマットで 文 字 変 数 の 長 さを 指 定 します */ x3=input(c,6.2); /* フォーマットで 文 字 変 数 の 長 さを 指 定 します */ x4=input(c,best12.); cards; 12345 123.45 1.23456e10 ; proc print data=a; proc contents data=a; (ログ) 505 options nocenter; 506 data a; 507 input c :$10.; /* 文 字 タイプとして 読 む */ 508 length x1 8; /* 数 値 タイプに 定 義 */ 509 x1=c; /* 自 動 変 換 */ 510 x2=input(c,5.); /* フォーマットで 文 字 変 数 の 長 さを 指 定 します */ 511 x3=input(c,6.2); /* フォーマットで 文 字 変 数 の 長 さを 指 定 します */ 512 x4=input(c,best12.); 513 cards; NOTE: 以 下 の 箇 所 で 文 字 値 を 数 値 に 変 換 しました ( 行 : カラム ) 509:6 NOTE: データセット WORK.A は 3 オブザベーション 5 変 数 です OBS c x1 x2 x3 x4 1 12345 12345.00 12345.00 123.450 12345.00 2 123.45 123.45 123.40 123.450 123.45 3 1.23456e10 12345600000.00 1.23 1.235 12345600000.00 変 数 と 属 性 の 昇 順 リスト # 変 数 タイプ 長 さ 1 c 文 字 10 2 x1 数 値 8 3 x2 数 値 8 4 x3 数 値 8 5 x4 数 値 8 61
数 値 タイプのインフォーマットの w.d の 指 定 は 読 み 取 る 元 のデータに 小 数 点 が 無 ければ 小 数 点 以 下 d 桁 の 数 値 として 読 み 込 むという 意 味 があります データに 小 数 点 があれば データの 値 が 優 先 されます [$CHARw.フォーマット インフォーマット] 文 字 変 数 値 は 普 通 の$w.インフォーマットで 読 むと 頭 のブランクは 左 詰 めされた 形 で 読 み 込 まれます $CHARw.インフォーマットはブランクを 左 詰 めせずにそのままの 形 で 読 み 込 むインフォーマットです (プログラム 2.2-11) 先 頭 のブランクを 左 詰 めせずにデータ 値 を 読 み 取 る data a; input @1 name $char10.; cards; 斎 藤 斎 藤 ; proc print data=a; OBS name 1 斎 藤 2 斎 藤 [FORMAT プロシジャ] FORMAT プロシジャはユーザ 独 自 のフォーマットを 定 義 するプロシジャです データ 値 は 短 いコード 値 で 入 力 しておき 計 算 もコード 値 で 集 計 しておき 集 計 結 果 をレポートするときにコード 値 を 日 本 語 の 説 明 フォーマットで 表 示 する 目 的 などに 非 常 に 良 く 使 われる 機 能 です PROC FORMAT オプション; VALUE ステートメント; PICTURE ステートメント; INVALUE ステートメント RUN; ( 主 なオプション) LIBRARY=SAS ライブラリ 参 照 名.カタログ 名 作 成 するフォーマット 定 義 カタログの 保 存 先 を 指 定 します CNTLOUT=SAS データセット 名 フォーマット 定 義 を 生 成 するための 決 まったフォーマット 定 義 用 変 数 を 含 む 出 力 SAS データセット 名 を 指 定 します CNTLIN=SAS データセット 名 決 まったフォーマット 定 義 用 変 数 を 含 む 入 力 SAS データセットを 指 定 しフォーマットカタログを 生 成 し ます 通 常 の VALUE ステートメントに 記 載 したものをコンパイルしてフォーマットを 生 成 するよりも はるかに 高 速 にフォーマットを 生 成 できますので 良 く 使 われます FMTLIB フォーマットカタログ 情 報 をプリントします 内 容 が 豊 富 な 場 合 非 常 にたくさんの 出 力 が 出 る 場 合 があ 62
りますので 注 意 が 必 要 です ( 良 く 使 うステートメント) (VALUE ステートメント) 個 々の 値 に 対 するフォーマットを 定 義 します VALUE フォーマット 名 フォーマット 定 義 ; (フォーマット 名 の 規 則 ) フォーマット 名 は 文 字 変 数 値 のフォーマットを 定 義 する 場 合 は 先 頭 は$で 始 め 2 文 字 目 以 降 最 後 から 2 番 目 までは SAS 名 前 付 けルールに 従 って 名 前 を 付 けます 数 値 の 場 合 は 最 後 から 2 番 目 までは SAS 名 の ルールを 適 用 して 名 前 を 付 けます いずれの 場 合 も 最 後 の 文 字 は 数 字 は 使 用 できません 長 さは$を 含 めて 32 文 字 以 内 です (フォーマット 定 義 方 法 ) 数 値 フォーマットの 場 合 は 値 ="フォーマット 値 " 文 字 フォーマットの 場 合 は " 値 "="フォーマット 値 " の 形 式 で 個 々の 値 に 付 けたいフォーマット 値 を 定 義 します 特 別 な 定 義 として 以 下 があります other="" という 指 定 を 1 つの VALUE ステートメントに 1 つだけ 指 定 できます これは それまでに 定 義 した 値 以 外 のすべての 値 に 適 用 されるフォーマットを 定 義 することを 意 味 します 例 ) VALUE $SEX "F"=" 女 性 " "M"=" 男 性 " other=" 記 入 なし" ; 数 値 フォーマットの 場 合 は 値 の 部 分 を 範 囲 定 義 できます VALUE AGE low-20=" 若 年 " 20<-<40=" 中 年 " 40-high=" 老 年 " ; -は 前 後 に=があるものと 解 釈 してください <-は 左 側 の 値 は 含 まないという 意 味 です 同 様 に -< は 右 側 の 値 を 含 まないという 意 味 low はマイナス とみなして 結 構 ですが 欠 損 値 は 含 まれません high は を 表 します (プログラム 2.2-12) ユーザ 定 義 フォーマットの 作 成 data sample; input ID name :$10. sex :$1. age height weight; 63
cards; 001 fujita M 30 175 70 002 suzuki F 29 168 59 003 takahashi M 32 180 85 004 tanaka M 40 178 77 ; proc format; value $sex "M"=" 男 性 " "F"=" 女 性 " other=" 不 明 " ; value age low-30=" 若 年 " 31-40=" 中 年 " 41-high=" 老 年 " other=" 不 明 " ; proc print data=sample; format sex $sex. age age.; (ログ) 1062 proc format; 1063 value $sex 1064 "M"=" 男 性 " 1065 "F"=" 女 性 " 1066 other=" 不 明 " 1067 ; NOTE: 出 力 形 式 $SEX を 作 成 しました 1068 value age 1069 low-30=" 若 年 " 1070 31-40=" 中 年 " 1071 41-high=" 老 年 " 1072 other=" 不 明 " 1073 ; NOTE: Format AGE は 既 にライブラリに 存 在 します NOTE: 出 力 形 式 AGE を 作 成 しました 1074 OBS ID name sex age height weight 1 1 fujita 男 性 若 年 175 70 2 2 suzuki 女 性 若 年 168 59 3 3 takahashi 男 性 中 年 180 85 4 4 tanaka 男 性 中 年 178 77 [コード 表 データからユーザ 定 義 フォーマットを 作 成 する 例 ] 一 般 に Excel その 他 のテキストファイルに 分 析 に 用 いる 文 字 型 データ 項 目 のコードと 対 応 する 説 明 テキス トが 保 管 されている 場 合 が 多 いと 思 います 情 報 が 多 い 場 合 VALUE ステートメントにコードとフォー 64
マットを 転 記 しながら 打 ち 込 むと 手 間 もかかりますし 間 違 いも 多 くなります また コード 情 報 が 何 千 ともなると これを 書 きこんだ VALUE ステートメントはコンパイルに 長 い 時 間 がかかることになりま す このような 場 合 は 決 まった 変 数 項 目 を 持 つ CNTL 形 式 の SAS データセットにコード 表 情 報 を 持 たせてお いて FORMAT プロシジャの CNTLIN= 指 定 を 行 うと 大 変 便 利 で しかも 高 速 にフォーマットカタログを 生 成 してくれます (プログラム 2.2-13) CNTL 形 式 SAS データセットの 作 成 と 呼 びこみ data cntl1; input fmtname :$8. start :$32. label :$60.; type="c"; end=start; hlo=""; cards; seibetu M 男 seibetu F 女 seibetu 99999 不 明 name fujita 藤 田 name suzuki 鈴 木 ; proc print data=cntl1; proc format cntlin=cntl1; proc print data=sample; format name $name. sex $seibetu.; (ログ) 61 data cntl1; 62 input fmtname :$8. start :$32. label :$60.; 63 type="c"; 64 end=start; 65 hlo=""; 66 cards; NOTE: データセット WORK.CNTL1 は 5 オブザベーション 6 変 数 です NOTE: DATA ステートメント 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.01 秒 CPU 時 間 0.00 秒 72 ; 73 proc print data=cntl1; NOTE: データセット WORK.CNTL1 から 5 オブザベーションを 読 み 込 みました NOTE: PROCEDURE PRINT 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.00 秒 CPU 時 間 0.00 秒 74 proc format cntlin=cntl1; NOTE: Format $SEIBETU は 既 にライブラリに 存 在 します NOTE: 出 力 形 式 $SEIBETU を 作 成 しました NOTE: 出 力 形 式 $NAME を 作 成 しました OBS fmtname start label type end hlo 65
1 seibetu M 男 C M 2 seibetu F 女 C F 3 seibetu 99999 不 明 C 99999 4 name fujita 藤 田 C fujita 5 name suzuki 鈴 木 C suzuki OBS ID name sex age height weight 1 1 藤 田 男 30 175 70 2 2 鈴 木 女 29 168 59 3 3 taka 男 32 180 85 4 4 tana 男 40 178 77 [DATA ステップによるレポート] 最 後 に DATA ステップでレポートの 例 を 経 験 します (プログラム 2.2-14) レポート 例 proc sort data=sample;by sex; data _null_; set sample end=end; by sex; file print header=header; if first.sex then do; n=0; /* 性 別 の 集 計 件 数 リセット */ wk=0; /* 性 別 のワーク 変 数 のリセット */ end; tot_n+1; /* 全 体 件 数 のカウント */ n+1; /* 性 別 件 数 のカウント */ tot_wk+height;/* 身 長 を 足 しこむ */ wk+height; /* 身 長 を 足 しこむ */ if last.sex then do; mean_height=wk/n; /* 性 別 の 平 均 身 長 を 計 算 */ put @5 " 性 別 :" sex @15 " 件 数 " +1 n " 件 " @30 " 平 均 身 長 :" +1 mean_height 6.2 "cm"; put @5 50*"-"; end; if end=1 then do; tot_mean_height=tot_wk/tot_n; /* 性 別 の 平 均 身 長 を 計 算 */ put @5 50*"="; put @5 " 全 体 :" @15 " 件 数 " +1 tot_n " 件 " @30 " 平 均 身 長 :" +1 tot_mean_height 6.2 "cm"; end; return; header: put; put @18 "**** 計 測 データの 集 計 ***"; put; tot_n=0; /* 全 体 集 計 件 数 リセット */ tot_wk=0; /* 身 長 の 平 均 を 求 めるためのワーク 変 数 のリセット */ retain tot_n tot_wk; return; 66
**** 計 測 データの 集 計 *** 性 別 :F 件 数 1 件 平 均 身 長 : 168.00cm -------------------------------------------------- 性 別 :M 件 数 3 件 平 均 身 長 : 177.67cm -------------------------------------------------- ================================================== 全 体 : 件 数 4 件 平 均 身 長 : 175.25cm FIRST.BY 変 数, LAST.BY 変 数 の 意 味 は 以 下 のとおりです これらの 変 数 は 値 を 与 えることはできませ ん またこの DATA ステップの 中 で 一 時 的 に 生 成 される 変 数 です (プログラム2.2-15) FIRST.BY 変 数, LAST.BY 変 数 の 値 data _null_; set sample end=end; by sex; first_sex=first.sex; last_sex=last.sex; end_=end; put sex= first_sex= last_sex= end_=; (ログ) sex=f first_sex=1 last_sex=1 end_=0 sex=m first_sex=1 last_sex=0 end_=0 sex=m first_sex=0 last_sex=0 end_=0 sex=m first_sex=0 last_sex=1 end_=1 [RETURN ステートメント,ラベルステートメント,LINK ステートメント,GOTO ステートメン ト] RETURN ステートメントは 実 行 中 の DATA ステップのループ 実 行 の 途 中 で 呼 出 元 の 位 置 に 戻 す 役 割 があ ります 戻 り 位 置 が 無 い 場 合 は DATA ステップの 最 初 に 戻 ります サブルーティン 呼 出 しの 代 表 的 な 例 は LINK ステートメントなどによるサブルーティンコールです サ ブルーティンはラベルステートメントで 始 まり RETURN ステートメントで 終 わります この 例 では FILE ステートメントの HEADER=ラベル 指 定 によるサブルーティンコールの 終 了 位 置 を 示 しており 呼 び 出 し た FILE ステートメントに 戻 ります (RETURN ステートメント) 実 行 ステートメント RETURN; 呼 出 し 元 がある 場 合 はラベル: RETURN; の 形 でラベルステートメントと 対 で 指 定 します この 場 合 は RETURN ステートメントを 実 行 すると 呼 び 出 し 元 に 戻 ります 呼 出 元 が 無 い 場 合 は DATA ステップの 最 初 の 実 行 ステートメントに 戻 ります (ラベルステートメント) 宣 言 ステートメント 67
ラベル 名 : このステートメントは 文 末 にセミコロン(;)は 不 要 です (コロン(:)で 終 わるステートメントと 解 釈 できま す ) (GOTO ステートメント) 実 行 ステートメント GOTO ラベル 名 ; プログラム 実 行 をラベル 名 で 参 照 する 位 置 に 移 動 します (LINK ステートメント) 実 行 ステートメント LINK ラベル 名 ; プログラム 実 行 をラベル 名 で 参 照 される 位 置 に 移 動 し RETURN ステートメントで LINK ステートメント の 次 のステートメントに 戻 ります 以 上 で 2 章 データ 加 工 は 終 了 です 68
3. レポーティング 3.1 集 計 データセットの 転 値 SQLプロシジャ ~ FREQ SUMMARY TRANSPOSE SQL プロシジャ SAS のデータ 集 計 機 能 は 基 本 的 に 度 数 集 計 を 行 う FREQ プロシジャと 連 続 変 数 の 合 計 値 や 平 均 値 を 集 計 する MEANS(SUMMARY)プロシジャがあります 前 半 ではこのような 統 計 計 算 行 うプロシジャについて 学 習 します プロシジャを 用 いたデータ 集 計 は 基 本 的 に 同 じ 変 数 (カラム)ごとにオブザベーション( 行 ) 方 向 に 集 計 を 行 うものです 場 合 によっては 変 数 とオブザベーションが 逆 に 並 んでいるようなデータの 形 になって いる 場 合 もあり 得 ます このような 場 合 は 行 列 を 逆 にして( 転 値 )しからプロシジャを 使 う 必 要 がでて きます そのために 用 意 されている TRANSPOSE プロジャについて 学 習 します 最 後 に SQL プロシジャ を 紹 介 します (プログラム3.1-1) データの 準 備 data trans; input ID :$3. date :yymmdd8. itemno :$3. section :$10. sales; ym=put(year(date),4.) "-" put(month(date),z2.); itemgrp=substr(itemno,1,1); sectgrp=scan(section,1,"_"); length=length(sectgrp); cards; 101 20101001 A01 TOKYO_2 256 102 20101006 B02 TOKYO_1 600 103 20101102 A01 KANAGAWA_2 123 102 20101111 B03 TOKYO_2 850 103 20101125 A03 KANAGAWA_3 45 101 20101130 B03 TOKYO_3 520 ; options nocenter; proc print data=trans; proc contents data=trans; OBS ID date itemno section sales ym itemgrp sectgrp length 1 101 18536 A01 TOKYO_2 256 2010-10 A TOKYO 5 2 102 18541 B02 TOKYO_1 600 2010-10 B TOKYO 5 3 103 18568 A01 KANAGAWA_2 123 2010-11 A KANAGAWA 8 4 102 18577 B03 TOKYO_2 850 2010-11 B TOKYO 5 5 103 18591 A03 KANAGAWA_3 45 2010-11 A KANAGAWA 8 6 101 18596 B03 TOKYO_3 520 2010-11 B TOKYO 5 変 数 と 属 性 の 昇 順 リスト # 変 数 タイプ 長 さ 1 ID 文 字 3 2 date 数 値 8 7 itemgrp 文 字 3 3 itemno 文 字 3 69
9 length 数 値 8 5 sales 数 値 8 8 sectgrp 文 字 200 4 section 文 字 10 6 ym 文 字 7 [ 良 く 使 う 文 字 列 操 作 演 算 子 と 文 字 関 数 ] ここで 文 字 関 数 などについて 紹 介 します この 例 の DATA ステップでは 文 字 列 結 合 演 算 子 ( )や 文 字 関 数 (SUBSTR,SCAN)を 用 いて 文 字 列 をくっつけたり 一 部 を 取 り 出 す 操 作 をしています 演 算 子 演 算 子 は 前 後 の 文 字 列 をつなぐ 演 算 子 です 12 例 ) d=a b c; 文 字 変 数 a,b,c の 値 をつなげた 値 を 文 字 変 数 d の 値 に 割 り 当 てます 注 意 :d の 長 さは 右 辺 の 文 字 変 数 の 長 さの 合 計 になります 文 字 変 数 に 入 っているブランクはそのまま 残 ります a="abc "( 長 さ 5), b="x "(3 文 字 ), c="zz "(4 文 字 ) このとき d="abc X ZZ "( 長 さ 12)となります SUBSTR 関 数 SUBSTR( 文 字 変 数, 開 始 位 置, 抽 出 文 字 数 ) 文 字 変 数 の 開 始 位 置 から 抽 出 文 字 数 分 の 長 さの 文 字 列 を 抽 出 します 例 ) sub=substr(d,1,6); sub="abc X" となります 注 意 :sub の 長 さは d の 長 さとなります SCAN 関 数 SCAN( 文 字 変 数, 番 号," 区 切 り 文 字 ") 指 定 の 区 切 り 文 字 のいずれかで 文 字 列 を 区 切 ったとき 指 定 の 番 号 の 部 分 文 字 列 を 抽 出 します 例 ) a="abcdef11abc1ab"; s1=scan(a,1,"abc1"); s1="def"となります 注 意 :s1 の 長 さを 事 前 に 定 義 していなかった 場 合 は SCAN 関 数 の 結 果 の 長 さは 200 になります LENGTH 関 数 LENGH( 文 字 変 数 ) 文 字 変 数 値 の 長 さを 返 します TRIM 関 数 登 場 していませんが 文 字 列 の 後 ろのブランクを 取 り 除 きます 例 ) d=trim(a) trim(b) trim(c); さきほどの a,b,c の 場 合 d="abcxzz" ( 長 さ 6)になります LEFT 関 数 これも 登 場 していませんが 数 値 を 文 字 に 変 換 したとき 右 詰 めされていますので 左 詰 12 演 算 子 と 同 じく 文 字 列 を 連 結 する 関 数 CAT.CATS,CATT があります CATS は 文 字 列 の 前 後 のブランク CATT は 後 ろのブランクのみを 取 り 除 いた 上 で 連 結 を 行 います 70
めするため 用 います LEFT( 文 字 列 ) 例 ) data _null_; do x=1 to 10; y=put(x, 2.); z="c" left(y); put x= z=; end; (ログ) x=1 z=c1 x=2 z=c2 x=3 z=c3 x=4 z=c4 x=5 z=c5 x=6 z=c6 x=7 z=c7 x=8 z=c8 x=9 z=c9 x=10 z=c10 LEFT 関 数 を 使 わないと z=c 1 などと, 間 にブランクがあきます COMPRESS 関 数 登 場 していませんが 文 字 列 の 中 に 含 まれるすべてのブランクを 取 り 除 きます 13 なお DBCS(Double Bytes Character Set) 関 数 という 一 連 の 文 字 列 操 作 関 数 も SAS には 用 意 されていま す これらはいわゆる 全 角 文 字 (" 漢 字 " "カナ" "かな" "ABC"など)と 半 角 文 字 ("abc","abc","123"な ど)が 混 在 した 文 字 列 に 対 して 全 角 文 字 半 角 文 字 それぞれを 1 個 の 文 字 として 正 しく 認 識 して 文 字 列 操 作 を 行 うための 関 数 です (substr 関 数 に 対 して ksubstr 関 数 scan 関 数 に 対 して kscan 関 数...という ように 頭 に K が 付 いた 文 字 列 操 作 関 数 があります ) 例 えば a=length("あいう 123");と 指 定 すると a=9 ですが b=klength("あいう 123");と 指 定 すると b=6 となります では 本 題 の FREQ プロシジャの 説 明 に 入 ります (プログラム 3.1-2) 単 純 集 計 proc freq data=trans; tables ym itemgrp sectgrp; FREQ プロシジャ 累 積 累 積 13 これに 対 して 文 字 列 中 のブランクは 削 除 せず さらに 文 字 列 の 前 後 に 1 個 ずつブランクをつけた 形 で 連 結 を 行 う COMPBL 関 数 があります 71
ym 度 数 パーセント 度 数 パーセント ----------------------------------------------------------- 2010-10 2 33.33 2 33.33 2010-11 4 66.67 6 100.00 累 積 累 積 itemgrp 度 数 パーセント 度 数 パーセント ----------------------------------------------------------- A 3 50.00 3 50.00 B 3 50.00 6 100.00 累 積 累 積 sectgrp 度 数 パーセント 度 数 パーセント ------------------------------------------------------------ KANAGAWA 2 33.33 2 33.33 TOKYO 4 66.67 6 100.00 (プログラム 3.1-3) 件 数 ( 度 数 )の 多 い 順 に 表 示 proc freq data=trans order=freq; tables ym itemgrp sectgrp; FREQ プロシジャ 累 積 累 積 ym 度 数 パーセント 度 数 パーセント ----------------------------------------------------------- 2010-11 4 66.67 4 66.67 2010-10 2 33.33 6 100.00 累 積 累 積 itemgrp 度 数 パーセント 度 数 パーセント ----------------------------------------------------------- A 3 50.00 3 50.00 B 3 50.00 6 100.00 累 積 累 積 sectgrp 度 数 パーセント 度 数 パーセント ------------------------------------------------------------ TOKYO 4 66.67 4 66.67 KANAGAWA 2 33.33 6 100.00 (プログラム 3.1-4) クロス 集 計 proc freq data=trans; tables itemgrp*sectgrp; FREQ プロシジャ 72
表 : itemgrp * sectgrp itemgrp sectgrp 度 数 パーセント 行 のパーセント 列 のパーセント KANAGAWA TOKYO 合 計 --------------+--------+--------+ A 2 1 3 33.33 16.67 50.00 66.67 33.33 100.00 25.00 --------------+--------+--------+ B 0 3 3 0.00 50.00 50.00 0.00 100.00 0.00 75.00 --------------+--------+--------+ 合 計 2 4 6 33.33 66.67 100.00 (プログラム 3.1-5) 3 重 クロス 集 計 と TABLES ステートメントのオプション 指 定 proc freq data=trans; tables ym*itemgrp*sectgrp/norow nocol nopercent; FREQ プロシジャ 表 1 : itemgrp * sectgrp 層 別 変 数 : ym=2010-10 itemgrp sectgrp 度 数 KANAGAWA TOKYO 合 計 --------+--------+--------+ A 0 1 1 --------+--------+--------+ B 0 1 1 --------+--------+--------+ 合 計 0 2 2 表 2 : itemgrp * sectgrp 層 別 変 数 : ym=2010-11 itemgrp sectgrp 度 数 KANAGAWA TOKYO 合 計 --------+--------+--------+ A 2 0 2 --------+--------+--------+ B 0 2 2 --------+--------+--------+ 73
合 計 2 2 4 (プログラム 3.1-6) 度 数 集 計 結 果 のデータセット 出 力 proc freq data=trans; tables ym/noprint out=ym; tables itemgrp*sectgrp/noprint out=item_sect; tables ym*itemgrp*sectgrp/noprint out=ym_item_sect; proc print data=ym; proc print data=item_sect; proc print data=ym_item_sect; OBS ym COUNT PERCENT 1 2010-10 2 33.3333 2 2010-11 4 66.6667 OBS itemgrp sectgrp COUNT PERCENT 1 A KANAGAWA 2 33.3333 2 A TOKYO 1 16.6667 3 B TOKYO 3 50.0000 OBS ym itemgrp sectgrp COUNT PERCENT 1 2010-10 A TOKYO 1 16.6667 2 2010-10 B TOKYO 1 16.6667 3 2010-11 A KANAGAWA 2 33.3333 4 2010-11 B TOKYO 2 33.3333 (プログラム 3.1-7) 出 力 データセットに 行 百 分 率 と 列 百 分 率 項 目 を 追 加 する OUTPCT オプション proc freq data=trans; tables ym/noprint out=ym(keep=ym count); tables itemgrp*sectgrp/noprint outpct out=item_sect; proc print data=ym; proc print data=item_sect; OBS ym COUNT 1 2010-10 2 2 2010-11 4 OBS itemgrp sectgrp COUNT PERCENT PCT_ROW PCT_COL 1 A KANAGAWA 2 33.3333 66.667 100 2 A TOKYO 1 16.6667 33.333 25 3 B TOKYO 3 50.0000 100.000 75 (プログラム 3.1-8) カイ 2 乗 検 定 を 行 いアイテム G とセクション G との 関 連 の 強 さを 調 べる proc freq data=trans; tables itemgrp*sectgrp/chisq; 74
FREQ プロシジャ 表 : itemgrp * sectgrp itemgrp sectgrp 度 数 パーセント 行 のパーセント 列 のパーセント KANAGAWA TOKYO 合 計 --------------+--------+--------+ A 2 1 3 33.33 16.67 50.00 66.67 33.33 100.00 25.00 --------------+--------+--------+ B 0 3 3 0.00 50.00 50.00 0.00 100.00 0.00 75.00 --------------+--------+--------+ 合 計 2 4 6 33.33 66.67 100.00 itemgrp * sectgrp の 統 計 量 統 計 量 自 由 度 値 p 値 ----------------------------------------------------------- カイ 2 乗 値 1 3.0000 0.0833 尤 度 比 カイ 2 乗 値 1 3.8191 0.0507 連 続 性 補 正 カイ 2 乗 値 1 0.7500 0.3865 Mantel-Haenszel のカイ 2 乗 値 1 2.5000 0.1138 ファイ 係 数 0.7071 一 致 係 数 0.5774 Cramer の V 統 計 量 0.7071 WARNING: セルの 100% において 期 待 度 数 が 5 より 小 さくなって います カイ 2 乗 検 定 は 妥 当 な 検 定 でないと 思 われます Fisher の 正 確 検 定 ----------------------------- セル (1,1) 度 数 (F) 2 左 側 Pr <= F 1.0000 右 側 Pr >= F 0.2000 表 の 確 率 (P) 0.2000 両 側 Pr <= P 0.4000 標 本 サイズ = 6 ここでは どの 商 品 もすべてのセクションで 同 じように 売 れているかどうかを 統 計 的 に 検 定 した 結 果 が 表 75
示 されています この 例 ではアイテム A は 神 奈 川 でアイテム B は 東 京 で 売 れているといった 偏 った 傾 向 が 見 られます このようにアイテム 別 の 売 上 がセクション 別 で 異 なる 場 合 偏 りがある 一 様 でない 関 連 がある 独 立 でない などと 言 います データからこのことが 普 遍 的 かどうかを 統 計 的 に 検 定 す るときは カイ 2 乗 検 定 という 統 計 的 検 定 法 を 使 います TABLES ステートメントに CHISQ オプ ションを 指 定 すると クロス 集 計 度 数 表 からカイ 2 乗 値 を 計 算 します カイ 2 乗 値 の 計 算 式 は 統 計 の 本 に 掲 載 されていますので 見 ていただくとして 大 事 なのは カイ 2 乗 値 を 含 むほぼすべての 統 計 量 は 帰 無 仮 説 とよばれる 単 純 な 状 態 (ここでは 2 つの 項 目 には 関 連 がなく 一 様 な 状 態 )を 仮 定 した 場 合 に こ のようなデータが 得 られる 確 率 をカイ 2 乗 値 とカイ 2 乗 値 を 求 める 2 つ 項 目 の (カテゴリー 数 -1) の 積 (これをカイ 2 乗 値 の 自 由 度 と 言 います) から 計 算 することです この 確 率 を 有 意 確 率 とか p 値 と 呼 び 検 定 統 計 量 の 隣 に 表 示 されます 表 示 されたカイ 2 乗 検 定 の 有 意 確 率 0.0833 は 2 つの 項 目 が 独 立 である 分 布 状 態 からこのようなデータが 得 られる 確 率 は 8.33%だということを 示 しています こ の 有 意 確 率 値 がある 程 度 小 さい 場 合 帰 無 仮 説 を 捨 てて 2 つの 項 目 には 関 連 があると 自 信 を 持 って 結 論 づけるのが 統 計 的 仮 説 検 定 の 目 的 です 帰 無 仮 説 に 対 して 採 用 する 仮 説 の 方 を 対 立 仮 説 と 呼 ぶこと もあります では どのくらい 関 連 があるかということが 問 題 になりますが 1 回 のサンプルデータで 決 める 場 合 は 集 計 結 果 データに 表 れた 偏 りを 推 計 結 果 とするのが 妥 当 と 考 えます さて 最 後 に FREQ プロシジャの 指 定 方 法 をまとめておきます [FREQ プロシジャ] PROC FREQ DATA= 入 力 データセット オプション; TABLES 指 定 / オプション; BY 変 数 ; WEIGHT 変 数 ; RUN; (PROC FREQ ステートメントの 良 く 使 うオプション) ORDER=DATA FORMATTED FREQ INTERNAL データセット 出 力 またはアウトプット 表 示 する 度 数 表 のカテゴリの 並 び 順 を 指 定 します デフォルトは INTERNAL( 内 部 値 ) つまりソート 順 です DATA... 入 力 データセットにおける 出 現 順, FORMATTED... フォーマットされた 値 の 順 (FORMAT ステートメントでフォーマット 指 定 されている 場 合 また 入 力 データセットにフォーマットが 定 義 されている 場 合 に 有 効 ) FREQ... 件 数 の 多 いカテゴリ 順 (TABLES ステートメントの 指 定 ) TABLES リクエスト; リクエストは 変 数 リストの 形 式 ( 各 変 数 の 単 純 集 計 )または 変 数 1* 変 数 2*... 変 数 k の 形 式 の 多 重 クロス 集 計 のリクエストをブランクで 区 切 って 指 定 できます また TABLES ステートメントは 複 数 指 定 できます 例 ) TABLES A B; A,B それぞれの 変 数 について 単 純 集 計 を 行 います TABLES A*B; 変 数 A と B のクロス 集 計 を 行 います 76
注 意 : 数 値 変 数 を TABLES ステートメントに 指 定 することは 可 能 ですが 個 々の 値 ごとの 度 数 を 集 計 す るため 多 量 のアウトプットが 表 示 されることがにつながります 数 値 変 数 の 値 の 種 類 とそれぞれの 該 当 件 数 を 調 べたい 場 合 は NOPRINT オプションと OUT=オプションを 指 定 してください (TABLES ステートメントで 良 く 使 うオプション) NOPRINT アウトプット 表 示 を 行 わないようにします 一 般 に 次 の OUT=オプションと 一 緒 に 使 います OUT= 出 力 データセット 名 度 数 集 計 結 果 を SAS データセットに 出 力 します 自 動 変 数 COUNT と PERCENT が 追 加 されます TABLES ステートメントに 複 数 のリクエスト 指 定 があると 最 後 のリクエストに 関 する 集 計 結 果 のみ 指 定 のデータセットに 出 力 します 複 数 のリクエストの 集 計 結 果 をすべてデータセット 出 力 するには 個 々の リクエストのみを TABLES ステートメントに 指 定 し TABLES ステートメントを 複 数 指 定 してください OUTPCT 多 重 集 計 リクエストで OUT= 指 定 がある 場 合 に 有 効 列 百 分 率 と 行 百 分 率 を 表 す 自 動 変 数 (PCT_COL, PCT_ROW)が 出 力 データセットに 追 加 されます SPARSE 他 次 元 クロス 集 計 の 場 合 出 現 していない 場 合 を 含 めて すべての 変 数 値 の 可 能 な 組 合 せの 集 計 件 数 をデ ータセットに 出 力 します CHISQ 2 次 元 度 数 集 計 表 におけるカイ 2 乗 検 定 を 行 います MEASURES カイ 2 乗 関 連 以 外 のさまざまな 関 連 度 の 指 標 をアウトプットします (WEIGHT ステートメント) WEIGHT 変 数 名 ; 重 み 変 数 を 指 定 します 指 定 された 変 数 の 値 だけそのオブザベーションがあるものとみなします 集 計 デ ータからクロス 集 計 表 を 作 成 するときなどに 使 用 します 変 数 値 の 小 数 点 以 下 は 切 り 捨 てられます また 欠 損 値 は 0 とみなされます WEIGHT ステートメントは 多 くのプロシジャで 共 通 に 使 えるステートメン トです 次 は 平 均 合 計 標 準 偏 差 といった 数 値 変 数 の 集 計 を 行 う MEANS プロシジャと SUMMARY プロシジャ です (プログラム 3.1-9) MEANS プロシジャ proc means data=trans; var sales; MEANS プロシジャ 分 析 変 数 : sales N 平 均 標 準 偏 差 最 小 値 最 大 値 ----------------------------------------------------------------- 77
6 399.0000000 309.9625784 45.0000000 850.0000000 ----------------------------------------------------------------- (プログラム 3.1-10) 統 計 量 のリクエスト proc means data=trans min max range mean median sum uss css var std; var sales; 分 析 変 数 : sales 最 小 値 最 大 値 範 囲 平 均 中 央 値 合 計 無 修 正 平 方 和 ---------------------------------------------------------------------------------------------- 45.0000000 850.0000000 805.0000000 399.0000000 388.0000000 2394.00 1435590.00 ---------------------------------------------------------------------------------------------- 修 正 済 平 方 和 分 散 標 準 偏 差 ------------------------------------------ 480384.00 96076.80 309.9625784 ------------------------------------------ Excel で 計 算 N x x^2 Σ x^2 avr(x) x-avr(x) (x-avr(x))^2 Σ (x-avr(x))^2 Σ (x-avr(x))^2/(n-1) SQRT(Σ(x-avr(x))^2/(N-1)) 256 65536 399-143 20449 600 360000 399 201 40401 6 123 15129 399-276 76176 1435590 850 722500 399 451 203401 480384 96076.80 309.9625784 45 2025 399-354 125316 520 270400 399 121 14641 Σ (x-avr(x))^2/n SQRT(Σ(x-avr(x))^2/N) 80064.00 282.9558269 連 続 変 数 値 に 関 する 統 計 量 は 位 置 に 関 するもの( 平 均 値 や 中 央 値 ) そして 変 動 (バラツキ)に 関 するもの ( 範 囲 や 分 散 や 標 準 偏 差 )があります バラツキは 個 々の 値 の 全 体 平 均 値 からの 距 離 ( 統 計 用 語 では 偏 差 と 呼 びます)を 集 計 して 求 めます 偏 差 はプラスマイナスがあり 単 純 に 足 し 算 するわけにいかないので 偏 差 を 2 乗 した 値 をすべてのデータについて 足 しこみ (これを 偏 差 平 方 和 と 呼 びます Σ 偏 差 ^2 =Σ (x^avr(x)^2) と 書 いた 記 法 がそれを 表 しています) 偏 差 平 方 和 を 件 数 N で 割 ってから 平 方 根 をとって 元 の 変 数 の 尺 度 に 戻 します( 標 準 偏 差 ) したがって データ 1 個 あたりの 偏 差 の 平 均 というのが 標 準 偏 差 の 意 味 です ただし 2 乗 した 値 の 平 均 をとってから 平 方 根 をとりますので 大 きい 偏 差 の 値 の 重 みが 大 きく なります 標 準 では 件 数 N で 無 くて 件 数 N から 1 を 引 いた 値 で 割 っています これはこの 値 がデータ の 自 由 度 を 表 し 求 める 分 散 をこのデータを 抽 出 した 母 集 団 における 標 準 偏 差 を 推 計 するために 用 いるた めです 6 個 のデータから 平 均 値 という 分 布 の 特 性 値 ( 母 数 パラメータと 呼 ばれます)を 計 算 して 得 てい るので 6 個 の 内 5 個 のデータの 値 を 知 れば 残 りの 1 個 のデータ 値 は 判 明 します したがって 手 元 にあ るデータの 自 由 度 は 5 ということになり 偏 差 平 方 和 を 自 由 度 で 割 った 値 を 母 集 団 における 分 散 推 計 値 と しています なお このように 自 由 度 で 割 った 分 散 のことを 不 偏 分 散 とよび 件 数 N で 割 った 分 散 のこと を 標 本 分 散 といって 区 別 します なお 単 に 分 散 とか 標 準 偏 差 と 言 った 場 合 は 不 偏 分 散 や 自 由 度 で 割 っ た 方 の 標 準 偏 差 ( 不 偏 標 準 偏 差 )を 意 味 する 場 合 が 多 いと 思 われます (プログラム 3.1-11) 標 本 分 散 と 標 本 標 準 偏 差 のリクエスト proc means data=trans vardef=n var std; var sales; 78
MEANS プロシジャ 分 析 変 数 : sales 分 散 標 準 偏 差 ---------------------------- 80064.00 282.9558269 ---------------------------- (プログラム 3.1-12) NOPRINT オプションと 統 計 量 のデータセット 出 力 proc means data=trans noprint; var sales; output out=sales_stat mean=mean std=std min=min max=max n=n; proc print data=sales_stat; OBS _TYPE FREQ_ mean std min max n 1 0 6 399 309.963 45 850 6 (プログラム 3.1-13) 複 数 の 変 数 の 統 計 量 を 出 力 データセットにリクエスト proc means data=trans noprint; var sales length; output out=sales_stat2 mean=mean1 mean2 std=std1 std2; proc print data=sales_stat2; OBS _TYPE FREQ_ mean1 mean2 std1 std2 1 0 6 399 6 309.963 1.54919 (プログラム 3.1-14) AUTONAME オプション proc means data=trans noprint; var sales length; output out=sales_stat2 mean= std=/autoname; proc print data=sales_stat2; sales_ length_ sales_ length_ OBS _TYPE FREQ_ Mean Mean StdDev StdDev 1 0 6 399 6 309.963 1.54919 (プログラム 3.1-15) グループ 別 集 計 proc means data=trans n mean sum; class sectgrp itemgrp; var sales; 79
MEANS プロシジャ 分 析 変 数 : sales オブザべーション sectgrp itemgrp 数 N 平 均 合 計 ------------------------------------------------------------------------------------------- KANAGAWA A 2 2 84.0000000 168.0000000 TOKYO A 1 1 256.0000000 256.0000000 B 3 3 656.6666667 1970.00 ------------------------------------------------------------------------------------------- (プログラム 3.1-16) グループ 別 集 計 アウトプット 表 示 桁 数 の 指 定 とデータセット 出 力 proc means data=trans n mean sum fw=10 maxdec=0; class sectgrp itemgrp; var sales; output out=group_stat n= mean= sum=/autoname; proc print data=group_stat; MEANS プロシジャ 分 析 変 数 : sales オブザべーション sectgrp itemgrp 数 N 平 均 合 計 ------------------------------------------------------------------------------------------- KANAGAWA A 2 2 84 168 TOKYO A 1 1 256 256 B 3 3 657 1970 sales_ sales_ OBS sectgrp itemgrp _TYPE FREQ_ sales_n Mean Sum 1 0 6 6 399.000 2394 2 A 1 3 3 141.333 424 3 B 1 3 3 656.667 1970 4 KANAGAWA 2 2 2 84.000 168 5 TOKYO 2 4 4 556.500 2226 6 KANAGAWA A 3 2 2 84.000 168 7 TOKYO A 3 1 1 256.000 256 8 TOKYO B 3 3 3 656.667 1970 _TYPE_ 自 動 変 数 の 値 は 以 下 のようにどのような 集 計 レベルを 表 すオブザベーションであるかを 識 別 し ます CLASS ステートメントに 指 定 した 変 数 の 数 だけビットパターンを 考 えます 80
この 場 合 は sectgrp,itemgrp の 2 つの 変 数 を 指 定 していますので 2 の 2 乗 =4 通 りのビットパターンがあ ります _TYPE_ 値 が 示 す 集 計 レベル sectgrp itemgrp 2 進 数 _TYPE_ 値 集 計 レベル 0 0 "00"B 0 全 体 0 1 "01"B 1 itemgrp 別 1 0 "10"B 2 sectgrp 別 1 1 "11"B 3 sectgrp 別 itemgrp 別 なお _FREQ_ 自 動 変 数 は CLASS 変 数 値 で 識 別 されるグループに 該 当 する 入 力 オブザベーション 数 を 表 します 統 計 量 キーワード N が 欠 損 値 で 無 いオブザベーション 数 を 表 すのに 対 して _FREQ_ は 欠 損 値 を 含 む 件 数 です (プログラム 3.1-17) NWAY オプションを 指 定 して 一 番 深 い _TYPE_ レベルのみリクエスト proc means data=trans noprint nway; class sectgrp itemgrp; var sales; output out=group_stat n= mean= sum=/autoname; proc print data=group_stat; sales_ sales_ OBS sectgrp itemgrp _TYPE FREQ_ sales_n Mean Sum 1 KANAGAWA A 3 2 2 84.000 168 2 TOKYO A 3 1 1 256.000 256 3 TOKYO B 3 3 3 656.667 1970 (プログラム 3.1-18) 特 定 の _TYPE_ レベルのみ 集 計 するようリクエスト proc means data=trans noprint; class sectgrp itemgrp; types () sectgrp sectgrp*itemgrp ; var sales; output out=group_stat n= mean= sum=/autoname; proc print data=group_stat; sales_ sales_ OBS sectgrp itemgrp _TYPE FREQ_ sales_n Mean Sum 1 0 6 6 399.000 2394 2 KANAGAWA 2 2 2 84.000 168 3 TOKYO 2 4 4 556.500 2226 4 KANAGAWA A 3 2 2 84.000 168 5 TOKYO A 3 1 1 256.000 256 6 TOKYO B 3 3 3 656.667 1970 81
では MEANS プロシジャの 指 定 方 法 をまとめておきます [MEANS プロシジャ] PROC MEANS DATA= 入 力 データセット オプション; CLASS 変 数 / オプション; TYPES リクエスト; WAYS リスト; VAR 変 数 ; ID 変 数 ; FREQ 変 数 ; WEIGHT 変 数 ; OUTPUT OUT= 出 力 データセット キーワード= 変 数 ; RUN; (PROC MEANS ステートメントの 良 く 使 うオプション) 統 計 量 キーワード たくさんありますが N,MEAN,SUM,STD,VAR,MIN,MAX,MEDIAN などを 良 く 使 うでしょう MISSING CLASS ステートメントで 指 定 した 分 類 変 数 の 欠 損 値 を 有 効 な 1 つのグループとして 集 計 対 象 にします 数 値 変 数 の 特 殊 欠 損 値 (.A~.Z および._)もそれぞれ 別 々の 有 効 なグループとみなします 注 :FREQ プロシジャの 場 合 は MISSING オプションを 指 定 しなくても OUT= 出 力 データセットには TABLES ステートメントの 変 数 に 欠 損 があっても 必 ずそのカテゴリは 出 力 されます それに 対 して MEANS プロシ ジャの 場 合 は MISSING オプションを 指 定 しないと 出 力 データセットには CLASS ステートメントに 指 定 し た 変 数 の 欠 損 カテゴリは 出 力 されません NOPRINT アウトプット 画 面 への 結 果 表 示 を 抑 制 します NWAY CLASS ステートメントに 指 定 した 全 変 数 のカテゴリ 組 み 合 わせの 集 計 結 果 のみデータセット 出 力 します 画 面 出 力 には 無 関 係 です TYPES ステートメントまたは WAYS ステートメントが 指 定 された 場 合 このオ プションは 無 効 になります VARDEF=DF N WDF WGT 分 散 と 標 準 偏 差 を 計 算 するときの 分 母 を 指 定 します DF( 自 由 度 )がデフォルト N は 非 欠 損 値 の 数 WDF と WGT は WEIGHT ステートメントの 指 定 がある 場 合 の 重 み 合 計 の 自 由 度 と 非 欠 損 件 数 ( 良 く 使 うステートメント) CLASS 変 数 ; 分 析 で 使 う 分 類 変 数 を 指 定 しておきます TYPES リクエスト; CLASS ステートメントで 指 定 した 変 数 の 集 計 したい 組 み 合 わせ 方 を 指 定 します 例 ) CLASS a b c; TYPES () a b a*c; ()は 全 体 (_TYPE_=0)のリクエストを 表 します 全 体 と a と b の 単 純 層 別 と a と c のクロス 層 別 で 分 類 した 集 計 をリクエストしています WAYS 数 字 ; 82
CLASS ステートメントで 指 定 した 変 数 の 組 み 合 わせ 数 を 指 定 します 例 ) CLASS a b c; WAYS 2; a,b,c の 3 変 数 から 2 変 数 を 取 る 全 組 み 合 わせを 層 別 とする 集 計 をリクエストします TYPES ステートメントの 指 定 とは OR 条 件 で 働 きます ID,BY,WEIGHT,FREQ,VAR ステートメント これらは 多 くのプロシジャで 共 通 に 使 えるステートメン トです なお WEIGHT ステートメントと FREQ ステートメントの 違 いは WEIGHT ステートメントは オブザベーションの 相 対 的 重 みを 表 し 少 数 点 以 下 の 値 も 有 効 で 統 計 量 の 計 算 に 使 われるのに 対 して FREQ ステートメントは 実 際 にオブザベーションが 変 数 値 の 数 だけ 重 複 して 入 力 されたものとみなし 整 数 値 に 切 り 捨 てされて 用 いられるということです ただし 度 数 集 計 を 行 う FREQ プロシジャでは WEIGHT ステートメントが FREQ ステートメントの 意 味 で 働 きます なお MEANS プロシジャは SUMMARY プロシジャという 別 名 を 持 っています 以 上 で MEANS プロシ ジャの 説 明 は 終 わりです [データセットの 転 値 ] Excelの 形 式 を 選 択 して 貼 り 付 け ダイアログにある 行 列 を 入 れ 替 える を 実 行 するSASのプロシジ ャがTRANSPOSEです (transデータセット) OBS ID date itemno section sales ym itemgrp sectgrp length 1 101 18536 A01 TOKYO_2 256 2010-10 A TOKYO 5 2 102 18541 B02 TOKYO_1 600 2010-10 B TOKYO 5 3 103 18568 A01 KANAGAWA_2 123 2010-11 A KANAGAWA 8 4 102 18577 B03 TOKYO_2 850 2010-11 B TOKYO 5 5 103 18591 A03 KANAGAWA_3 45 2010-11 A KANAGAWA 8 6 101 18596 B03 TOKYO_3 520 2010-11 B TOKYO 5 (プログラム3.1-19) SASデータセットの 転 値 (オブザベーションと 変 数 の 入 れ 替 え) proc transpose data=trans out=trans2; proc print data=trans2; (ログ) NOTE: データセット WORK.TRANS から 6 オブザベーションを 読 み 込 みました NOTE: データセット WORK.TRANS2 は 3 オブザベーション 7 変 数 です OBS _NAME_ COL1 COL2 COL3 COL4 COL5 COL6 1 date 18536 18541 18568 18577 18591 18596 2 sales 256 600 123 850 45 520 3 length 5 5 8 5 8 5 数 値 タイプの3 個 の 変 数 (date,sales,length)のみ 選 択 され 転 値 されました 元 の 変 数 名 は 自 動 変 数 _NAME_ の 値 となっています 元 のデータセットの1 番 目 のオブザベーションの 値 は 自 動 的 に 変 数 COL1 の 値 になり 2 番 目 のオブザベーションは 変 数 COL2...6 番 目 のオブザベーションは 変 数 COL6の 値 に 格 納 されました 83
(プログラム3.1-20) 転 値 したい 変 数 の 指 定 proc transpose data=trans out=trans2; var itemgrp sectgrp; proc print data=trans2; OBS _NAME_ COL1 COL2 COL3 COL4 COL5 COL6 1 itemgrp A B A B A B 2 sectgrp TOKYO TOKYO KANAGAWA TOKYO KANAGAWA TOKYO SASデータセットはデータセルごとに 数 値 型 文 字 型 のタイプを 混 在 させることはできませんので VAR ステートメントに 指 定 できる 変 数 タイプはすべて 数 値 型 か すべて 文 字 型 を 指 定 する 必 要 があります (プログラム3.1-21) BYグループ 処 理 proc freq data=trans; table sectgrp*itemgrp/noprint out=cross(drop=percent); proc print data=cross; proc transpose data=cross out=cross2; by sectgrp; id itemgrp; var count; proc print data=cross2; OBS sectgrp itemgrp COUNT 1 KANAGAWA A 2 2 TOKYO A 1 3 TOKYO B 3 OBS sectgrp _NAME LABEL_ A B 1 KANAGAWA COUNT 度 数 2. 2 TOKYO COUNT 度 数 1 3 以 上 のようにTRANSPOSEプロシジャを 使 ってSASデータセットのオブザベーションと 変 数 を 変 換 するこ とができます 注 意 点 としては 次 の 点 が 挙 げられます ID 変 数 値 は BYステートメントがあればBYグループ 内 で 無 ければ 全 オブザベーションで32 文 字 以 内 でユニークで 無 ければなりません またID 変 数 値 にSAS 変 数 名 の 命 名 規 則 に 違 反 する 文 字 があったときは すべて "_" アンダースコアに 変 換 されます なお 数 値 変 数 をID 変 数 指 定 すると 変 数 名 の 頭 に 必 ず"_" がつきます [TRANSPOSE プロシジャ] PROC TRANSPOSE DATA= 入 力 データセット OUT= 出 力 データセット オプション; VAR 変 数 ; 84
BY 変 数 ; ID 変 数 ; RUN; (PROC TRANSPOSEステートメント) OUT= 指 定 を 省 略 すると _DATA_データセットが 指 定 されたものとみなし DATAn (nは 数 字 )の 自 動 データセット 名 が 作 成 されます PREFIX= 変 数 名 のPREFIX 転 値 後 の 自 動 変 数 名 COL1,COL2,...,COLn のCOLの 代 わりにつけるPREFIXを 指 定 します IDステートメ ントが 指 定 されたなら 各 ID 値 の 頭 に 指 定 したPREFIXが 付 いた 変 数 名 となります 例 ) prefix=var VAR1,VAR2,... という 名 前 の 変 数 になります [SQL プロシジャ] SAS の 中 で SQL の 文 法 によるデータ 検 索 作 成 を 行 うプロシジャが SQL プロシジャです PROC SQL ステートメントで SQL プロシジャに 入 ると SQL の 世 界 の 構 文 ルールに 従 います RUN ス テートメントは 無 意 味 で QUIT ステートメントで SQL プロシジャを 終 了 します SQL 句 のセパレータは ブランクでは 無 くカンマが 使 われます PROC SORT でソートしていなくても ORDER BY 句 を 使 うこ とができます PROC PRINT を 行 わなくても SQL の 中 で SELECT ステートメントをサブミットすると 検 索 結 果 がアウトプット 画 面 に 表 示 されます というように SAS の 中 から SQL の 世 界 が 開 きます (プログラム 3.1-22) テーブル 定 義 とデータ 挿 入 options nocenter nodate nonumber; proc sql; create table sample (ID char(3), sex char(1), birth num informat=date9. format=yymmdds10., height num); insert into sample values("001","m","01jan1960"d,175) values("002","f","11dec1985"d,160); title "PROC SQL SELECT Statement"; select * from sample; (ログ) 51 options nocenter nonumber nodate; 52 proc sql; 53 create table sample 54 (ID char(3), 55 sex char(1), 56 birth num informat=date9. format=yymmdds10., 57 height num); NOTE: テーブル WORK.SAMPLE ( 行 数 0 列 数 4) が 作 成 されました 58 insert into sample 59 values("001","m","01jan1960"d,175) 60 values("002","f","11dec1985"d,160); NOTE: 2 行 が WORK.SAMPLE に 挿 入 されました 61 title "PROC SQL SELECT Statement"; 85
62 select * from sample; PROC SQL SELECT Statement ID sex birth height ------------------------------ 001 M 1960/01/01 175 002 F 1985/12/11 160 (プログラム 3.1-23) 既 存 のテーブル 読 込 みによるテーブル 作 成 proc sql; create table sample2 as select ID, birth as birth2 from sample; proc print data=sample2; (ログ) 64 proc sql; 65 create table sample2 as 66 select ID, birth as birth2 67 from sample; NOTE: テーブル WORK.SAMPLE2 ( 行 数 2 列 数 2) が 作 成 されました PROC SQL SELECT Statement OBS ID birth2 1 001 1960/01/01 2 002 1985/12/11 (プログラム 3.1-24) テーブル 結 合 data japan; input ID :$3. name :$10. sex :$1.; cards; 001 fujita M 002 suzuki F 003 takahashi M 004 tanaka M ; data us; input ID :$3. name :$10. age height weight; cards; 101 browne 30 160 51 102 gibson 40 160 48 ; proc sql number; select id, name, sex from japan union select id, name, "", age, height, weight from us; PROC SQL SELECT Statement 86
Row ID name sex age height weight ---------------------------------------------------------- 1 001 fujita M... 2 002 suzuki F... 3 003 takahashi M... 4 004 tanaka M... 5 101 browne 30 160 51 6 102 gibson 40 160 48 (プログラム 3.1-25) VIEW の 作 成 と 集 計 data trans; input ID :$3. date :yymmdd8. itemno :$3. section :$10. sales; ym=put(year(date),4.) "-" put(month(date),z2.); itemgrp=substr(itemno,1,1); sectgrp=scan(section,1,"_"); length=length(sectgrp); cards; 101 20101001 A01 TOKYO_2 256 102 20101006 B02 TOKYO_1 600 103 20101102 A01 KANAGAWA_2 123 102 20101111 B03 TOKYO_2 850 103 20101125 A03 KANAGAWA_3 45 101 20101130 B03 TOKYO_3 520 ; proc sql; create view view1 as select id, count(id) as number label=" 件 数 ", avg(sales) as average_sales label=" 平 均 売 上 " from trans group by id having average_sales ge 100; proc print data=view1; (ログ) 199 proc sql; 200 create view view1 as 201 select id, count(id) as number label=" 件 数 ", avg(sales) as average_sales label=" 平 均 売 上 " 202 from trans 203 group by id 204 having average_sales ge 100; NOTE: SQL ビューは WORK.VIEW1 定 義 されました PROC SQL SELECT Statement average_ OBS ID number sales 1 101 2 388 2 102 2 725 というように 際 限 がありませんので このあたりで 終 わりにします 87
SQL プロシジャは ANSI( 米 国 規 格 協 会 ) が 発 表 している SQL ガイドラインにほとんど 適 合 しています したがって SQL 言 語 が 得 意 な 人 は 簡 単 に 使 いこなすことができると 思 います ただし SAS の SQL プ ロシジャは SAS 環 境 で 使 うことを 前 提 としているため データベース 操 作 関 連 の 機 能 (Commit や Roll Back 機 能 など)は 含 まれていません 14 指 定 方 法 は 膨 大 となるため ここで 記 載 できません マニュアル 等 をご 参 照 ください [データベースからデータ 抽 出 のための SQL プロシジャ] 補 足 として SAS ACCESS プロダクトを 導 入 して ORACLE, DB2, Teradata などのデータベーステーブ ルからデータを SAS データセットに 抽 出 15 する 場 合 の SQL を 例 示 します [SQL パススルー 方 式 による DB2 データベースからのデータアクセス 例 ] proc sql; connect to DB2(user=username password=password datasrc=sample); create table A as select * from connection to DB2 ( select * from STAFF where job='mgr' ); disconnect from DB2; quit; 上 記 の 例 は DB2 データベース sample 内 のテーブル STAFF の 全 項 目 を 列 名 job の 値 が 'Mgr' に 一 致 す るレコードのみ SAS データセット WORK.A に 読 み 取 るプログラム 例 となっています () 内 にデータベ ース 用 SQL を 記 述 します 同 じ 結 果 は 以 下 の(A),(B)いずれの 指 定 でも 得 られます しかし パススルー 方 式 の 方 が 高 速 です なお (A) 方 式 の 場 合 はデータベース 用 SQL では 無 く SAS の SQL として 有 効 でなければなりません (A) libname in DB2 datasrc=sample; proc sql; create table A as select * from in.staff where job='mgr' ; quit; (B) libname in DB2 datasrc=sample; data A; set in.staff; if job='mgr'; 14 データベースとのインターフェースをとる SAS ACCESS プロダクトを 導 入 するとデータベース 関 連 のコマンドも 利 用 可 能 になります 15 各 データベースごとに SAS ACCESS プロダクトの 導 入 が 必 要 です 88
3.2 レポーティングとマクロ 処 理 ~ TABULATE プロシジャとマクロ 処 理 SAS 講 習 の 最 後 は SAS のレポーティング 関 連 で SAS ユーザの 高 い 支 持 を 受 けていると 思 われる TABULATE プロシジャを 中 心 に 学 習 します TABULATE プロシジャは 罫 線 入 りの 多 重 クロス 表 を 作 成 する ためのプロシジャですが 表 のレイアウトやセルに 入 れる 統 計 量 や 比 率 の 指 定 が 少 ない 指 定 で 行 えるとい う 特 長 があります 明 細 データから 度 数 や 合 計 値 や 平 均 値 などのクロス 集 計 表 を 作 成 することもできます が 大 容 量 データに 対 しては 一 旦 FREQ や MEANS(SUMMARY)を 用 いて 要 約 結 果 をデータセットに 出 力 しておいて そのデータセットの 入 力 値 から 作 表 する 方 が 作 りたい 表 の 形 式 を 試 行 錯 誤 するような 場 合 は 時 間 的 に 有 利 になります このように FREQ や MEANS を 組 み 合 わせて TABULATE を 使 うこともあ ります 簡 易 なレポートを 作 成 するためには REPORT プロシジャがあります しかし このプロシジャが 行 えるの は 2 日 目 の 最 後 に 紹 介 した DATA ステップで 作 成 するレポートと 同 程 度 のレポートであり 使 うメリット がそれほど 無 いと 思 われますので 講 習 対 象 から 外 しました 最 後 のマクロ 処 理 は SAS に 慣 れたユーザがさらに 便 利 に SAS を 使 えるようにするための 機 能 です こ れまで 見 てきたように SAS 言 語 のプログラミングとは DATA ステップと PROC ステップという 実 行 単 位 に 分 けて 逐 次 的 に 実 行 するよう 最 初 から 最 後 のステップまで 明 示 的 に 書 いた SAS ステートメントの 集 合 という 形 でした しかし SAS マクロ 機 能 を 使 うと プログラムの 途 中 で 得 られた 計 算 結 果 によっ て 別 のプロシジャを 実 行 したり 別 のデータ 加 工 処 理 を 行 ういった 処 理 を 事 前 に プログラミングし ておくことができます また 汎 用 的 に 使 いたいプログラムを SAS マクロとして 定 義 しておくことにより 部 品 として 再 利 用 しやすくなります SAS マクロ 機 能 は SAS マクロ 言 語 という 言 語 体 系 を 持 っており SAS 言 語 と 良 く 似 たステートメントや 関 数 演 算 子 などが 使 えますが すぐに 使 いこなせるものではあ りません ここではマクロ 言 語 を 使 った 簡 単 なプログラムの 例 を 実 行 し SAS マクロ 機 能 を 理 解 するこ とを 学 習 の 目 標 とします [TABULATE プロシジャ] これまで 学 習 したように FREQ プロシジャや MEAN プロシジャは 明 細 データから 分 類 変 数 値 の 組 み 合 わせごとに 度 数 集 計 や 数 値 変 数 の 合 計 や 平 均 を 集 計 しますが 画 面 アウトプットはあまり 見 やすいもの ではありません FREQ プロシジャは 分 類 変 数 を 重 ねた 度 数 集 計 を 他 のどのプロシジャより 素 早 く 実 行 する 能 力 を 持 っていますが 3 つ 以 上 の 分 類 変 数 の 組 み 合 わせを 同 じクロス 集 計 表 の 中 に 表 示 する 能 力 を 持 っていません また MEANS プロシジャは 分 類 変 数 のすべての 組 み 合 わせ 階 層 における 連 続 変 数 の 集 計 値 を 同 時 に 計 算 する 能 力 がありますが 分 類 変 数 の 値 の 組 み 合 わせを 識 別 変 数 として 統 計 量 を 横 一 線 に 並 べて 表 示 する 以 外 の 表 現 方 法 を 持 っていません TABULATE プロシジャはこのような 分 類 変 数 値 の 組 み 合 わせを われわれが 認 識 しやすいような 多 重 クロス 表 のイメージで 表 現 します (プログラム 3.1-1 で 作 成 した trans データセット) OBS ID date itemno section sales ym itemgrp sectgrp length 1 101 18536 A01 TOKYO_2 256 2010-10 A TOKYO 5 2 102 18541 B02 TOKYO_1 600 2010-10 B TOKYO 5 3 103 18568 A01 KANAGAWA_2 123 2010-11 A KANAGAWA 8 4 102 18577 B03 TOKYO_2 850 2010-11 B TOKYO 5 5 103 18591 A03 KANAGAWA_3 45 2010-11 A KANAGAWA 8 89
6 101 18596 B03 TOKYO_3 520 2010-11 B TOKYO 5 (プログラム 3.2-1) 度 数 集 計 options ls=132 ps=60; proc tabulate data=trans; class itemgrp sectgrp; tables itemgrp, sectgrp; CLASS ステートメントは MEANS プロシジャと 同 じくプロシジャで 用 いる 分 類 変 数 を 指 定 します TABLE ステートメントに 登 場 する 分 類 変 数 は 必 ず CLASS ステートメントで 指 定 しておく 必 要 があります TABLES ステートメントで 作 成 したい 表 イメージをリクエストします アウトプットは FREQ プロシジャの 表 示 と 良 く 似 ています TABLES ステートメントの 中 の カンマ(,) は 作 成 する 表 の 次 元 を 意 味 します カンマは 0 個 から 2 個 まで 指 定 でき それぞれ 1 次 元 から 3 次 元 までの 表 の 作 成 を 意 味 します この 例 の 場 合 カンマは 1 個 ですので 2 次 元 の 表 をリクエストすることになります カンマの 左 側 の 指 定 は 行 方 向 ( 行 次 元 ) 右 側 の 指 定 は 列 方 向 ( 列 次 元 )に 配 置 された 形 のクロス 表 イメージを 作 成 します この 例 の 行 次 元 には 指 定 した 分 類 変 数 itemgrp で 変 数 名 と 値 が 各 行 に 表 示 されています また 列 次 元 には 分 類 変 数 sectgrp が 指 定 され 変 数 名 の 行 値 の 行 さらに 統 計 量 (N)の 3 行 にわたって 表 示 されています 表 のセルの 値 は 次 元 のクロスで 定 義 される 分 類 変 数 の 組 み 合 わせと 統 計 量 の 種 類 に 従 って 集 計 されます この 例 では 分 類 変 数 同 士 の 組 み 合 わせのときのデフォルトの 統 計 量 である 度 数 (N)が 自 動 的 に 用 いられて います なお OPITONS ステートメントで 指 定 している LS=,PS=はそれぞれアウトプット 画 面 の 幅 (LineSize)と 1 ページの 長 さ(PageSize)を 指 定 します LS は 64 から 256 まで PS は 15 から 32767 までの 範 囲 で 指 定 できます (プログラム 3.2-2) 次 元 の 指 定 proc tabulate data=trans; class itemgrp sectgrp ym; tables itemgrp sectgrp ym; tables itemgrp, sectgrp ym; tables itemgrp, sectgrp, ym; 90
TABLES ステートメントにカンマなし 1 個 2 個 をそれぞれ 指 定 した 場 合 のアウトプットを 表 示 しまし た 1 次 元 指 定 は 列 方 向 への 配 置 を 意 味 します 2 次 元 指 定 は 行 と 列 に 配 置 されます 3 次 元 指 定 は FREQ プロシジャの BY グループ 処 理 と 同 じように ページと 行 と 列 に 配 置 されます (プログラム 3.2-3) ブランクとアスタリスク 演 算 子 proc tabulate data=trans; class itemgrp sectgrp ym; tables itemgrp sectgrp, ym; tables itemgrp*sectgrp, ym; 91
ブランク( )は 前 後 の 表 現 を 並 列 させる 意 味 を 持 ちます アスタリスク(*) は 前 後 の 表 現 を 交 差 (クロス) させる 意 味 を 持 ちます なお カンマ(,)もアスタリスク(*)の 意 味 を 持 ちます (セルの 参 照 ) 最 初 の TABLES ステートメントは 統 計 量 N の 指 定 が 省 略 されています tables itemgrp sectgrp, ym*n; この*N の*はクロスの 意 味 ではなく 統 計 量 の 指 定 を 行 うときの 決 まりです * 統 計 量 キーワード という 書 き 方 をします ( 例 *mean *sum *std など) TABULATE がこの TABLES ステートメントをどのように 解 釈 して 表 を 作 成 しているかをなぞってみまし ょう (1) カンマが 1 個 あるので 行 次 元 の 指 定 itemgrp sectgrp を 解 釈 して 分 類 変 数 itemgrp をまず 配 置 し ( 変 数 名 と itemgrp の 各 値 をそれぞれ 1 つの 行 に 配 置 ) その 下 に 分 類 変 数 sectgrp を 並 列 配 置 ( 変 数 名 と sectgrp の 各 値 をそれぞれ 1 つの 行 に 配 置 )します 一 方 列 次 元 の 指 定 ym*n を 解 釈 して 分 類 変 数 名 ym を 表 示 する 行 ym の 値 を 表 示 する 行 そして 統 計 量 N を 表 示 する 行 の 3 行 を 作 成 します これで 表 のイメージが 完 成 しました (2) 次 に 各 セルの 値 を 計 算 します 行 と 列 が 交 差 するセルにはその 行 変 数 の 値 と 列 変 数 の 値 で 定 義 される グループについて 指 定 された 統 計 量 を 計 算 します この 指 定 の 場 合 は 上 の 4 つのセルは 行 次 元 分 類 変 数 itemgrp と 列 次 元 分 類 変 数 ym との 交 差 を 表 すセルとなっており 統 計 量 は N です また 下 の 4 つのセルは 行 次 元 分 類 変 数 sectgrp と 列 次 元 分 類 変 数 ym, との 交 差 を 表 すセルです 以 上 TABULATE がどのように TABLES ステートメントを 解 釈 し 表 のイメージとセルの 値 を 計 算 するか を 簡 単 に 説 明 しました 92
さて カンマがアスタリスクと 同 じく 次 元 間 の 指 定 同 士 を 交 差 させる 働 きがあることに 注 意 すると 表 のイメージは 異 なりますが この 指 定 は 次 の 指 定 と 同 じです tables itemgrp*ym*n sectgrp*ym*n; これは 最 初 の 指 定 を 展 開 した 形 となっており 表 の 形 こそ 異 なりますが 生 成 されるセルの 数 と 値 は 同 じ になります TABULATE を 使 って アスタリスク( 交 差 )とブランク( 並 列 )を 組 み 合 わせて 複 雑 な 表 を 作 成 しようとすると すべてのセルが 矛 盾 の 無 い 分 類 定 義 と 1 つの 統 計 量 (さらに 次 で 登 場 する 1 つのフォー マット)で 定 義 されていないと 作 表 不 能 となるため 最 初 はエラーの 嵐 に 見 舞 われることになると 思 いま す このとき TABLES ステートメントの 指 定 が 正 しいかどうかを 調 べるのに 1 次 元 に 展 開 してみるこ とをお 勧 めします 分 類 定 義 や 統 計 量 などの 各 要 素 の 指 定 に 重 複 や 矛 盾 がないかどうかを 確 認 しやすくな ります 2 番 目 の TABLES ステートメントの 指 定 を 1 次 元 に 展 開 して 各 セルの 定 義 を 説 明 してくださ い tables itemgrp*sectgrp, ym; カンマを 展 開 すると??? (プログラム 3.2-4) 分 析 変 数 の 指 定 と 変 数 ラベル 統 計 量 フォーマットの 指 定 proc tabulate data=trans f=5.; class itemgrp sectgrp; var sales; tables itemgrp="アイテムg", sectgrp="セクションg"*sales=" 売 上 " *(n=" 件 数 " sum=" 合 計 "*f=comma8. mean=" 平 均 "*f=6.1) /rts=12; VAR ステートメントは MEANS プロシジャと 同 じく 合 計 や 平 均 を 計 算 する 数 値 タイプの 変 数 ( 分 析 変 数 ) を 指 定 します MEANS プロシジャでは 省 略 可 能 でしたが TABULATE プロシジャでは TABLES ステート メントに 登 場 する 分 析 変 数 は 必 ず VAR ステートメントで 指 定 しておく 必 要 があります TABLES ステートメントの 中 で 以 下 の 指 定 が 登 場 しています 変 数 名 ="ラベル"*f=フォーマット ="ラベル" 93
変 数 名 や 統 計 量 の 代 わりに 指 定 したラベルを 使 用 するようにする 指 定 です 列 次 元 の 分 析 変 数 名 や 統 計 量 に 対 してブランクラベル (="" または =" ") を 指 定 した 場 合 で 並 列 す る 列 次 元 の 統 計 量 のラベル 指 定 も 同 じく="" または =" "であった 場 合 は その 行 自 体 が 削 除 されます そ れ 以 外 は 表 示 がブランクになるだけで 該 当 行 または 該 当 列 は 削 除 されません 変 数 名 のラベルは LABEL ステートメントで 指 定 しても 表 示 できます 同 様 に 統 計 量 キーワードのラベルは KEYLABEL ステートメントでも 指 定 できます TABLES ステートメントにおいて 指 定 すると 同 じ 統 計 量 キーワードに 別 々のラベルを 与 えることがで きます *f=フォーマット 統 計 量 キーワード もしくは 統 計 量 キーワード="ラベル" 指 定 に 続 いて 列 次 元 の 統 計 量 の 表 示 フォーマッ トを 指 定 します f=w.d の 形 で w は 該 当 するセルの 表 示 幅 ( 縦 罫 線 を 除 く 表 示 列 幅 ) d は w の 中 での 小 数 点 の 桁 数 指 定 で す デフォルトのフォーマットは f=12.2 となっています PROC TABULATE ステートメントの f=フォーマット オプション PROC TABULATE ステートメントで f=フォーマットを 指 定 すると デフォルトフォーマットが 指 定 した フォーマットに 変 わります しかし TABLES ステートメントに 指 定 した 各 セルのフォーマット 指 定 がそ の 統 計 量 のフォーマット 出 力 として 優 先 されます TABLES ステートメントのオプション / を 指 定 してからオプションを 指 定 します RTS= 行 タイトルスペース 行 次 元 の 分 類 変 数 項 目 表 示 スペース 幅 をカラム 数 で 指 定 します この 値 は 前 後 の" "を 含 んだ 幅 の 長 さにな ります デフォルトは LineSize の 値 の 1/4 に 設 定 されています (LS=132 の 場 合 RTS=33) (プログラム 3.2-5) 列 次 元 の 分 析 変 数 と 統 計 量 の 表 示 の 削 除 title " 売 上 集 計 "; proc tabulate data=trans f=5.; class itemgrp sectgrp ym; var sales; tables itemgrp, (sectgrp ym)*sales=" "*sum=""*f=comma8./rts=12; label itemgrp="アイテムg" sectgrp="セクションg" ym=" 年 月 "; 列 次 元 の 変 数 名 に 続 く sales=""*sum="" の 指 定 により 分 析 変 数 これらの 行 が 削 除 されています 列 次 元 の (sectgrp ym) とカッコでくくることにより 2 つの 分 類 変 数 を 最 上 位 で 並 列 させる 指 定 を 簡 潔 94
に 表 現 しています (プログラム 3.2-6) 合 計 欄 の 追 加 title; proc tabulate data=trans f=5.; class itemgrp sectgrp ym; var sales length; tables itemgrp ALL, (ALL sectgrp ym)*sales=" "*sum=""*f=comma8./rts=12; label itemgrp="アイテムg" sectgrp="セクションg" ym=" 年 月 "; keylabel all=" 全 体 "; (プログラム 3.2-7) 小 計 と 合 計 proc tabulate data=trans f=5.; class itemgrp sectgrp ym; var sales length; tables itemgrp ALL, (ALL sectgrp)*(ym ALL=" 合 計 ")*sales=" " *sum=""*f=comma8./rts=12; tables itemgrp ALL, (ALL*(ym ALL=" 合 計 ") sectgrp*(ym ALL=" 小 計 "))*sales=" " *sum=""*f=comma8./rts=12; label itemgrp="アイテムg" sectgrp="セクションg" ym=" 年 月 "; keylabel all=" 全 体 "; 95
(プログラム 3.2-8) 百 分 率 の 計 算 proc tabulate data=trans f=5.; class itemgrp sectgrp; tables itemgrp ALL, (sectgrp ALL)*(N PCTN*f=5.2) /rts=12; tables itemgrp ALL, (sectgrp ALL)*(N PCTN<itemgrp*sectgrp itemgrp*all ALL*sectgrp ALL*ALL>*f=6.2) /rts=20; label itemgrp="アイテムg" sectgrp="セクションg"; keylabel all=" 全 体 " N=" 件 数 " PCTN=" 件 数 百 分 率 "; PCTN 統 計 量 キーワードは 以 下 のように 指 定 します PCTN< 分 母 > < 分 母 >は 省 略 すると その 分 類 組 み 合 わせ 定 義 のレベルの 合 計 という 意 味 になります 1 番 目 の TABLES ステートメントの 場 合 は PCTN の< 分 母 > 指 定 を 省 略 しています この TABLES 指 定 を 展 開 すると 96
itemgrp*sectgrp*pctn itemgrp*all*pctn ALL*sectgrp*PCTN ALL*ALL*PCTN の 4 つの 部 分 に 展 開 されます それぞれの 部 分 における< 分 母 >は 上 記 の*PCTN の 左 側 になっているとい う 意 味 です これらの 分 類 組 み 合 わせの 合 計 件 数 は いずれも 全 体 件 数 の 6 となりますので 全 体 件 数 を 分 母 とする 件 数 百 分 率 を 計 算 することを 意 味 しています 2 番 目 の TABLES ステートメントの PCTN の 指 定 は 分 布 の 指 定 を 明 示 したものです 結 果 が 同 じになっ ていることを 確 認 してください (プログラム 3.2-9) 行 百 分 率 の 計 算 proc tabulate data=trans f=5.; class itemgrp sectgrp; tables itemgrp ALL, (sectgrp ALL)*(N PCTN<sectgrp ALL sectgrp ALL*ALL>*f=6.2) /rts=20; label itemgrp="アイテムg" sectgrp="セクションg"; keylabel all=" 全 体 " N=" 件 数 " PCTN=" 行 百 分 率 "; TABLES ステートメントの PCTN キーワードの< 分 母 > 指 定 を 以 下 のように 変 えています itemgrp*sectgrp*pctn に 対 しては <sectgrp> 各 itemgrp 値 ごとに 分 母 は sectgrp の 値 を 全 部 足 した 値 itemgrp*all*pctn に 対 しては <ALL> 各 itemgrp 値 ごとに 分 母 は sectgrp の ALL 値 ALL*sectgrp*PCTN に 対 しては <sectgrp> itemgrp の ALL 値 の 分 母 は sectgrp の 値 を 全 部 足 した 値 ALL*ALL*PCTN に 対 しては <ALL+ALL> 全 体 合 計 値 の 分 母 はその 全 体 合 計 値 すべての PCTN のセルで 行 百 分 率 を 計 算 することになります (プログラム 3.2-10) PCTSUM proc tabulate data=trans f=5.; class itemgrp sectgrp ym; var sales length; tables itemgrp ALL, (ALL sectgrp ym)*sales=" " *(sum=" 売 上 高 "*f=comma8. PCTSUM*f=6.1)/rts=12; 97
tables itemgrp ALL, (ALL sectgrp ym)*sales=" " *(sum=" 売 上 高 "*f=comma8. PCTSUM<itemgrp*ALL itemgrp*sectgrp itemgrp*ym ALL*ALL ALL*sectgrp ALL*ym> *f=8.1)/rts=20; label itemgrp="アイテムg" sectgrp="セクションg" ym=" 年 月 "; keylabel all=" 全 体 " PCTSUM=" 構 成 比 率 %"; PCTN と 同 様 PCTSUM の< 分 母 >のデフォルトは 全 体 です TABLES 指 定 を 展 開 してみましょう itemgrp*all*sales*pctsum itemgrp*sectgrp*sales*pctsum itemgrp*ym*sales*pctsum ALL*ALL*sales*PCTSUM ALL*sectgrp*sales*PCTSUM ALL*ym*sales*PCTSUM 以 上 の 6 つの 部 分 に 分 かれることがわかります では 上 記 アウトプットの 構 成 比 率 をすべて 列 百 分 率 の 表 示 に 変 えるプログラムを 書 いて ください tables itemgrp ALL, (ALL sectgrp ym)*sales=" " *(sum=" 売 上 高 "*f=comma8. 98
PCTSUM<itemgrp*ALL itemgrp*sectgrp itemgrp*ym ALL*ALL ALL*sectgrp ALL*ym> *f=8.1)/rts=20; の PCTSUM<>を 書 き 換 えてください (こんなアウトプット) [ 分 母 の 定 義 を 省 略 した 行 百 分 率 列 百 分 率 の 指 定 ] 統 計 量 キーワード ROWPCTN, COLPCTN, ROWPCTSUM, COLPCTSUM を 使 用 すると 分 母 の 指 定 が 不 要 になります これらを 指 定 した 場 合 は 行 または 列 の 総 合 計 欄 の 値 が 表 示 されているいないに 関 わら ず 分 母 に 指 定 されたものとみなされます (プログラム 3.2-9' ) ROWPCTN キーワードを 用 いた 行 百 分 率 の 計 算 proc tabulate data=trans f=5.; class itemgrp sectgrp; tables itemgrp ALL, (sectgrp ALL)*(N ROWPCTN*f=6.2) /rts=20; label itemgrp="アイテムg" sectgrp="セクションg"; keylabel all=" 全 体 " N=" 件 数 " ROWPCTN=" 行 百 分 率 "; [ 数 値 変 数 を 分 母 の 定 義 に 使 用 した 百 分 率 の 例 ] 通 常 百 分 率 を 表 示 する 場 合 は CLASS ステートメントに 指 定 した 分 類 変 数 (の 交 差 定 義 )を 分 母 に 指 定 しますが 百 分 率 を 表 示 したいセルに 対 する 分 類 変 数 による 交 差 定 義 が 指 定 されていない 場 合 は 百 分 率 は 計 算 できません 以 下 の 例 は 数 値 変 数 としてアンケート 回 答 者 ID を VAR ステートメントに 指 定 し ておき q2_1, q2_2, q2_2 の 3 つの 多 重 回 答 項 目 について 合 計 件 数 の 回 答 者 人 数 に 対 する 百 分 率 を 集 計 しています ID を 分 母 に 指 定 することにより 顧 客 ID の 種 類 数 の 合 計 件 数 (この 場 合 は 101~106 の 99
6 件 )が 分 母 に 用 いられます なお 多 肢 選 択 項 目 q1 は CLASS 変 数 に 指 定 し 通 常 の 集 計 を 行 っていま す (プログラム 3.2-11) 多 重 回 答 アンケートの 集 計 data mult; input ID q1 q2_1 q2_2 q2_3; cards; 101 1 1 1. 102 2 1 1 1 103 1.. 1 104 3. 1 1 105 1.. 1 106.A 1 1 1 ; proc tabulate data=mult missing; class q1; var q2_1 q2_2 q2_3 ID; tables q1 q2_1 q2_2 q2_3,(n=" 件 数 " pctn<q1 ID ID ID >=" 構 成 比 率 %"*f=5.1)/rts=6; 以 上 で TABULATE は 終 了 です [SAS マクロ 機 能 ] Base SAS プロダクトに 含 まれる 機 能 で プログラムのモジュール 化 やアプリケーション 開 発 に 威 力 を 発 揮 します DATA ステップや PROC ステップの 上 位 に 位 置 する 機 能 で 通 常 の SAS ステートメントより 前 に 解 釈 実 行 されます マクロ 機 能 はプログラミング 言 語 仕 様 を 持 つマクロ 言 語 とマクロ 言 語 で 書 かれた SAS コード 部 分 を 解 釈 実 行 するマクロプロセサの 2 つの 要 素 で 構 成 されます 主 なマクロ 機 能 として マクロ 定 義 (マクロ 保 存 マクロ 呼 出 しを 含 む) グローバルマクロ 変 数 自 動 マクロ 変 数 DATA ステ ップとのインターフェースなどがあります マクロの 利 用 により 以 下 のようなプログラムコーディング 上 のメリットが 得 られます - 同 じ 処 理 を 繰 り 返 し 行 う 場 合 のコーディングの 簡 素 化 - 再 帰 処 理 - 処 理 のモジュール 化 -アプリケーション 作 成 100
(プログラム 3.2-12) %LET ステートメントとマクロ 変 数 options symbolgen; %let pgm1=%str(data a;a=1;proc print data=a;); &pgm1; options nosymbolgen; (ログ) 554 options symbolgen; 555 %let pgm1=%str(data a;a=1;proc print data=a;); 556 &pgm1; SYMBOLGEN: マクロ 変 数 PGM1 を data a;a=1;proc print data=a; に 展 開 します SYMBOLGEN: 値 のマクロ 引 用 した 文 字 のうち プリントするために 引 用 符 を 取 り 除 いたものがあります OBS a 1 1 %LET ステートメントはマクロ 変 数 に 値 を 定 義 します マクロ 変 数 は 作 成 した 後 SAS セッションのどこ でも 参 照 できます マクロ 機 能 (%か&で 始 まるワード)は DATA ステップや PROC ステップの 実 行 を 管 理 する SAS プロセサより 前 に 認 識 され 実 行 されます この 場 合 参 照 されたマクロ 変 数 の 値 (テキスト) は SAS プログラムとして SAS プロセサに 認 識 され 実 行 されます %LET マクロ 変 数 名 = 値 ; マクロ 変 数 の 値 は 常 にテキストです 引 用 符 ("")はそのままテキストとして 認 識 されます (プログラム 3.2-13) マクロ 定 義 options mprint; %macro a; data _null_; age=int(input(put(today(),yymmddn8.),8.)/10000-&birth/10000); put age=; %mend a; %let birth=20101019; %a (ログ) 578 options mprint; 579 %macro a; 580 data _null_; 581 age=int(input(put(today(),yymmddn8.),8.)/10000-&birth/10000); 582 put age=; 583 584 %mend a; 585 586 %let birth=20101019; 587 %a MPRINT(A): data _null_; SYMBOLGEN: マクロ 変 数 BIRTH を 20101019 に 展 開 します 101
MPRINT(A): MPRINT(A): MPRINT(A): age=int(input(put(today(),yymmddn8.),8.)/10000-20101019/10000); put age=; age=0 %で 始 まるステートメントはマクロステートメントです %MACRO ステートメントはマクロ 定 義 を 開 始 するステートメントで %MEND ステートメントで 定 義 を 終 了 し ます %MACRO マクロ 名 (パラメータ) / オプション; マクロ 名 は SAS 名 の 命 名 規 則 に 準 拠 します この 例 ではマクロ 名 は a で パラメータは 定 義 されていません マクロ a の 処 理 は yyyymmdd のフォーマット 形 式 の 文 字 列 値 が 入 ったマクロ 変 数 &birth の 値 を 外 部 か ら 受 け 取 り 今 日 現 在 の 年 齢 を DATA ステップで 計 算 し 結 果 をログに 書 き 出 すというものです %LET ステートメントでマクロ 変 数 birth に 20101019 を 代 入 しています そして %a という 指 定 は %マクロ 名 という 文 法 で 指 定 したマクロを 呼 び 出 すものです このステートメントは 最 後 のセミコロンが 不 要 です もしも 指 定 すると それは%マクロ 名 の 指 定 部 分 で 定 義 されたマクロを 呼 び 出 し SAS 言 語 に 展 開 されたステートメントが SAS プロセサに 送 り 込 まれた 後 に さらに 1 個 のセミコロンが 送 り 込 まれサブミットされることを 意 味 します この 例 のように 大 抵 の 場 合 はマクロ 定 義 の 最 後 は RUN;といったステートメントで 終 了 しているので もう 1 個 セミコロンがあっても 結 果 に 影 響 ありません (プログラム 3.2-14) マクロ 定 義 のパラメータ %macro a(birth,format=best12.); data _null_; age=int(input(put(today(),yymmddn8.),8.)/10000-&birth/10000); put age= &format; %mend a; %a(20101019,format=z8.) (ログ) 604 %macro a(birth,format=best12.); 605 data _null_; 606 age=int(input(put(today(),yymmddn8.),8.)/10000-&birth/10000); 607 put age= &format; 608 609 %mend a; 610 611 %a(20101019,format=z8.) MPRINT(A): data _null_; SYMBOLGEN: マクロ 変 数 BIRTH を 20101019 に 展 開 します 102
MPRINT(A): age=int(input(put(today(),yymmddn8.),8.)/10000-20101019/10000); SYMBOLGEN: マクロ 変 数 FORMAT を z8. に 展 開 します MPRINT(A): put age= z8.; MPRINT(A): age=00000000 マクロ 定 義 でパラメータを 指 定 しておくと パラメータ 値 を 指 定 してマクロ 呼 出 を 行 えます パラメータの 指 定 方 法 には 定 位 置 パラメータとキーワードパラメータの 2 通 りの 指 定 ができます ( 定 位 置 パラメータ) そのマクロ 定 義 で 用 いているマクロ 変 数 名 をカンマで 区 切 って 指 定 します 初 期 値 を 持 つことができませ ん マクロを 呼 び 出 すときは 必 ず 定 義 された 順 にカンマで 区 切 ってパラメータ 値 を 指 定 します キー ワードパラメータより 先 に 定 義 しておかなくてはなりませんし 呼 び 出 すときも 先 に 値 を 指 定 しなければ なりません この 例 では マクロ 変 数 birth は 定 位 置 パラメータとして 定 義 しています (キーワードパラメータ) マクロ 変 数 名 = 初 期 値 の 形 式 で 指 定 します このパラメータは 初 期 値 を 与 えていますので 呼 出 時 に 指 定 しなくてもかまいません この 例 では マクロ 変 数 format を 初 期 値 best12. で 定 義 しています (プログラム 3.2-15) 処 理 の 分 岐 %macro a(birth); data _null_; age=int(input(put(today(),yymmddn8.),8.)/10000-&birth/10000); call symput("age",left(put(age,best12.))); %put AGE=&AGE; %if &AGE<0 %then %put %str( 入 力 されたbirthの 値 は 未 来 の 年 月 日 を 表 しています.); %else %put %str(あなたの 年 齢 は %trim(&age) 歳 です.); %mend a; options nomprint nosymbolgen; %a(20001019) %a(20201019) (ログ) 770 %a(20001019) NOTE: DATA ステートメント 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.00 秒 CPU 時 間 0.00 秒 AGE=10 あなたの 年 齢 は 10 歳 です. 771 %a(20201019) NOTE: DATA ステートメント 処 理 ( 合 計 処 理 時 間 ): 103
処 理 時 間 CPU 時 間 0.00 秒 0.00 秒 AGE=-9 入 力 されたbirthの 値 は 未 来 の 年 月 日 を 表 しています. マクロ 言 語 は %IF ステートメントや%trim 関 数 など DATA ステップのステートメントや 関 数 と 同 じよう なステートメントや 関 数 を 備 えています (プログラム 3.2-16) プログラムのモジュール 化 %macro NOBS(data); %global NOBS; data _null_; call symput("nobs",compress(put(nobs,best12.))); stop; set &data nobs=nobs; %mend NOBS; %NOBS(trans) %put &NOBS; (ログ) 754 %NOBS(trans) MACROGEN(NOBS): MACROGEN(NOBS): MACROGEN(NOBS): MACROGEN(NOBS): MACROGEN(NOBS): data _null_; call symput("nobs",compress(put(nobs,best12.))); stop; set trans nobs=nobs; NOTE: DATA ステートメント 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.00 秒 CPU 時 間 0.00 秒 755 %put &NOBS; 6 (プログラム 3.2-17) アプリケーション 開 発 %macro NOBS(data); %*global NOBS; data _null_; call symput("nobs",compress(put(nobs,best12.))); stop; set &data nobs=nobs; %mend NOBS; %macro means1(data); %local NOBS; %let dsid=%sysfunc(open(&data)); %if &dsid<=0 %then %do; %put %str(データセット &data が 見 つかりません.); %goto eee; %end; %let rc=%sysfunc(close(&dsid)); 104
%NOBS(&DATA) %if &NOBS=0 %then %do; %put %str(データセット%data にはオブザベーションがありません.); %goto eee; %end; proc means data=&data; %eee: %mend means1; %symdel NOBS; %means1(sample) %means1(trans) (ログ) 807 %means1(sample) データセット sample が 見 つかりません. 808 %means1(trans) NOTE: DATA ステートメント 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.00 秒 CPU 時 間 0.00 秒 NOTE: データセット WORK.TRANS から 6 オブザベーションを 読 み 込 みました NOTE: PROCEDURE MEANS 処 理 ( 合 計 処 理 時 間 ): 処 理 時 間 0.01 秒 CPU 時 間 0.01 秒 変 数 N 平 均 標 準 偏 差 最 小 値 最 大 値 --------------------------------------------------------------------------- date 6 18568.17 25.0871813 18536.00 18596.00 sales 6 399.0000000 309.9625784 45.0000000 850.0000000 length 6 6.0000000 1.5491933 5.0000000 8.0000000 --------------------------------------------------------------------------- ( 終 了 ) 105
[ 別 表 1] DATA ステップで 使 えるステートメント 一 覧 ABORT ARRAY ステートメント 名 asign( 割 り 当 て) ATTRIB BY CALL CARDS CARDS4 CONTINUE DATA DATALINES DATALINES4 DELETE DO DO, iterative( 繰 り 返 し DO) DO UNTIL DO WHILE DROP ELSE END ERROR FILE FORMAT GO TO IF, Subsetting(サブセット IF) IF~THEN INFILE INFORMAT INPUT KEEP LABEL Labels, Statement LEAVE LENGTH LINK LIST MERGE OUTPUT PAGE DATAステップの 実 行 を 中 断 する 変 数 配 列 の 宣 言 役 割 変 数 名 = 式 ;の 形 で 指 定 する 等 号 の 左 辺 の 変 数 に 右 辺 の 式 の 値 を 割 り 当 てる 1つの 変 数 の 属 性 (タイプ 長 さ フォーマット インフォーマット ラベル)をまとめて 宣 言 する 指 定 の 変 数 のソート 順 にオブザベーションが 並 んでいることを 示 す BYグループ 処 理 を 行 う 場 合 に 必 須 とな る CALLルーティン( 複 数 の 戻 り 値 を 許 す 関 数 )の 呼 び 出 し これ 以 降 にカードイメージデータが 記 述 されていることを 示 す 同 セミコロンや2バイト 文 字 を 含 むデータを 正 しく 読 み 取 る 場 合 にCARDSに 代 えて 用 いる DOループ(DOグループ) 処 理 の 中 で 用 い ENDステートメントまで 強 制 移 動 させてDOループ 処 理 にとどまるこ とを 指 示 する DATAステップの 開 始 とこのステップで 作 成 する 出 力 データセット 名 を 宣 言 する CARDSステートメントの 別 名 CARDS4ステートメントの 別 名 現 在 処 理 中 のオブザベーションの 処 理 を 中 断 ( 出 力 データセットに 書 き 込 まない)して 次 のオブザベーション の 処 理 に 移 るためにDATAステップのはじめに 戻 る ENDステートメントと 対 で 用 い 条 件 式 に 合 致 した 場 合 の 実 行 範 囲 をDO~ENDで 囲 んで 指 定 する 囲 まれた 範 囲 をDOループまたはDOグループと 呼 ぶ 繰 り 返 しDOステートメントの1つで iterativeの 部 分 には 変 数 名 = 開 始 値 TO 終 了 値 BY 増 分 値 というDO ループ 処 理 の 実 行 条 件 指 定 が 入 る 同 UNTIL( 条 件 式 )に 指 定 した 条 件 を 満 たさない 範 囲 でDOループ 処 理 を 実 行 する 同 WHILE( 条 件 式 )に 指 定 した 条 件 を 満 たしている 範 囲 でDOループ 処 理 を 実 行 する 出 力 データセットに 含 めない 変 数 を 指 定 する IF~THENステートメントと 共 に 用 い IF 条 件 に 合 致 しない 場 合 の 処 理 を 記 述 する DOステートメントと 対 で 用 い DOループ 処 理 範 囲 を 指 定 する 強 制 的 にエラーを 発 生 させる データ 値 の 出 力 先 ( 外 部 ファイル 名 リスティング ログなど)を 指 定 する 指 定 の 変 数 に 出 力 フォーマットを 指 定 する 指 定 のラベル 名 が 書 かれたプログラム 位 置 に 次 の 処 理 を 強 制 移 動 させる 指 定 の 条 件 に 合 致 するオブザベーションのみこれ 以 降 の 処 理 に 進 むことを 許 可 する 指 定 の 条 件 に 合 致 する 場 合 の 処 理 を 記 述 する 条 件 に 合 致 しない 場 合 の 処 理 は 続 くELSEステートメントで 記 述 する 外 部 入 力 ファイル 名 を 指 定 する 指 定 の 変 数 に 入 力 フォーマットを 指 定 する 外 部 ファイルから 指 定 の 変 数 名 の 値 を 指 定 の 入 力 形 式 で 読 み 取 る 出 力 データセットに 含 める 変 数 を 指 定 する 指 定 の 変 数 に 変 数 ラベルを 定 義 する ラベル 名 :(コロン)の 指 定 により GO TOやLINKステートメントにより 強 制 移 動 させるプログラム 位 置 を 示 す DOループ(DOグループ) 処 理 の 中 で 用 い ENDステートメントの 次 のステートメントまで(ラベルを 指 定 してい た 場 合 はラベル 位 置 まで) 強 制 移 動 させてDOループ 処 理 を 抜 けることを 指 示 する 作 成 する 変 数 のタイプと 長 さを 定 義 する 指 定 のラベル 名 が 書 かれたプログラム 位 置 からRETURNステートメントまでの 範 囲 に 記 述 されたサブルーティ ンに 処 理 を 強 制 移 動 させた 後 移 動 前 の 位 置 に 戻 るよう 指 示 する 変 数 の 値 をログに 書 き 出 す 複 数 のデータセットを 横 に 結 合 した 形 でオープンする 指 定 の 出 力 データセットに 現 在 処 理 中 のオブザベーションを 書 き 出 す 改 ページを 指 示 する DATAステッププログラミングによるレポート 作 成 用 ステートメント 106
PUT PUTLOG RENAME RETAIN RETURN RUN SELECT SET SKIP STOP Sum UPDATE 外 部 ファイルやリスティング 出 力 やログへ 指 定 の 変 数 名 の 値 を 指 定 の 出 力 形 式 で 書 き 出 す FILEステートメントの 指 定 する 書 き 出 し 先 に 無 関 係 に ログにメッセージを 書 き 出 す 変 数 名 を 変 更 する 指 定 の 変 数 値 の 現 在 値 を 次 のオブザベーション 処 理 に 変 わっても 初 期 化 せずに 保 持 するよう 宣 言 する 最 初 のDATAステートメントに 処 理 を 戻 す LINKステートメントからの 分 岐 の 場 合 はLINKの 次 のステートメント に 処 理 を 戻 す DATAステップの 記 述 の 終 了 を 明 示 的 に 指 定 する 条 件 選 択 のために 条 件 を 指 定 する データセットを 入 力 のためにオープンする 複 数 のデータセットを 指 定 した 場 合 MERGEと 異 なり 縦 に 結 合 した イメージでオープンする ブランク 行 を 書 き 出 す DATAステッププログラミングによるレポート 作 成 用 ステートメント DATAステップの 処 理 を 中 止 する 変 数 名 + 式 の 形 で 指 定 する DATAステップのループ 処 理 中 の 変 数 値 は 右 辺 の 式 の 値 の 累 積 値 を 値 として 持 つ UPDATE Master Transact;の 形 の 指 定 となり 必 ずBYステートメントと 共 に 指 定 する Masterデータセットの 値 をTransactデータセットの 値 で 更 新 する 場 合 に 用 いる [ 別 表 2] PROC ステップの 種 類 プロシジャ 名 PROC APPEND PROC COMPARE PROC CONTENTS PROC COPY PROC CORR PROC DATASETS PROC DELETE PROC EXPORT PROC FORMAT PROC FREQ PROC IMPORT PROC MEANS PROC OPTIONS PROC PRINT PROC PRINTTO PROC RANK PROC SCORE PROC SORT PROC SQL PROC SUMMARY PROC TABULATE PROC TRANSPOSE PROC UNIVARIATE 役 割 データセット 最 後 のオブザベーションの 後 に 他 のデータセットのオブザベーションを 追 加 する 2つのデータセットの 内 容 を 比 較 する データセットのコンテンツ 情 報 (オブザベーション 数 などの 一 般 属 性 と 変 数 名 や 変 数 タイプなどの 変 数 属 性 )を 表 示 したりデータセットに 出 力 する データセットをコピーする 相 関 係 数 を 計 算 する 特 定 のライブラリに 格 納 されているデータセット 名 のリストを 表 示 したり 個 々のデータセットの 名 前 の 変 更 削 除 などを 行 う また 個 々のデータセットに 関 する 属 性 の 表 示 や 編 集 を 行 う 上 記 DATASETSプロシジャの 機 能 の 一 部 であるデータセットの 削 除 を 行 う データセットを 外 部 ファイル 形 式 に 変 換 する IMPORTプロシジャの 逆 の 操 作 を 行 う ユーザー 定 義 フォーマットを 作 成 する 度 数 集 計 を 行 う n 次 元 クロス 集 計 も 可 能 特 定 の 形 式 (CSV 形 式 など)の 外 部 ファイルからデータを 読 み 取 りデータセットに 変 換 する 変 数 ごとの 基 本 統 計 ( 平 均 値 標 準 偏 差 など)を 計 算 する オプション 設 定 を 変 更 する データセットの 値 をリスト 表 示 する リスティング 出 力 の 出 力 先 をファイルに 変 更 する 変 数 値 の 順 序 を 計 算 する スコア 係 数 とデータ 値 の 積 和 によるスコアを 計 算 する オブザベーションを 指 定 の 変 数 値 の 順 に 並 び 替 える SQL 言 語 によるデータ 検 索 加 工 を 行 う MEANSと 同 じく 変 数 ごとの 基 本 統 計 ( 平 均 値 標 準 偏 差 など)を 計 算 する 度 数 平 均 百 分 率 を 含 む 多 重 クロス 集 計 表 を 作 成 する データセットを 転 置 ( 行 と 列 を 交 換 )する 変 数 ごとの 基 本 統 計 ( 平 均 値 標 準 偏 差 など)を 計 算 する MEANS,SUMMARYより 詳 細 [ 別 表 3] グローバルステートメント 一 覧 ステートメント 名 役 割 Comment(コメント) *(アスタリスク 記 号 )で 始 まるステートメント 任 意 のコメントを 記 述 できる ENDSAS WPSセッションを 終 了 する FILENAME 外 部 ファイル 参 照 名 を 定 義 する 107
FILENAME_DDE FILENAME_EMAIL FOOTNOTE %INC %INCLUDE LIBNAME MISSING ODS EXCLUDE ODS HTML ODS LISTING ODS OUTPUT ODS SELECT ODS SHOW ODS TRACE OPTIONS RUN TITLE PAGE SKIP X DDE( 動 的 データ 交 換 ) 機 能 によるアプリケーションとWPS 間 のデータ 交 換 を 行 う WPSからEmailを 送 る フットノートテキストを 定 義 する %INCステートメントの 省 略 形 外 部 ファイルに 書 かれたソースコードを 読 み 込 み 実 行 する データセットライブラリ 参 照 名 を 定 義 する 数 値 タイプ 変 数 の 入 力 値 に 書 かれた 欠 損 を 表 す 文 字 を 指 定 する ODS 機 能 による 選 択 リストの 中 から 除 外 項 目 を 選 ぶ HTML 出 力 を 管 理 する また どのオブジェクトをHTML 出 力 するかを 制 御 する 特 定 項 目 のリスティング 出 力 を 管 理 する 特 定 項 目 のデータセット 出 力 を 管 理 する ODS 機 能 による 選 択 リストの 中 から 選 択 項 目 を 選 ぶ ODS 選 択 リストの 表 示 ODS 出 力 に 関 するメッセージをログに 書 き 出 すかどうかを 切 り 替 える 各 種 オプションの 設 定 を 変 更 する DATAステップ PROCステップのステートメントの 指 定 を 終 了 しステップを 実 行 する タイトルテキストを 定 義 する ログを 新 しいページに 切 り 替 える ログにブランク 行 を1 行 書 いて 改 行 する コマンドプロンプトを 呼 び 出 す [ 別 表 4] 演 算 子 一 覧 分 類 シンボル 別 表 記 意 味 例 算 術 + 足 し 算 c=a+b - 引 き 算 d=10-x * 掛 け 算 y=2*x / 割 り 算 z=x/y ** 累 乗 計 算 value=2**(x+1) 論 理 & AND かつ if (a=1) & (b=10) OR または if (a=1) (b=10) ^ NOT 否 定 if ^(z=1) 比 較 = EQ 等 しい if a=b ^= NE 等 しくない if a NE b < LT より 小 さい( 未 満 ) if a<b <= LE 等 しいかより 小 さい( 以 下 ) if a LE 5 > GT より 大 きい( 超 ) if b GT 15*x >= GE 等 しいかより 大 きい( 以 上 ) if b>=16*x 符 号 + プラス( 正 の 数 ) y=+1 - マイナス( 負 の 数 ) y=-1 最 小 >< 小 さい 方 の 値 z=(x><y) 最 大 <> 大 きい 方 の 値 H=(x<>y<>z) 文 字 列 検 索 IN いずれかの 文 字 列 に 一 致 する if name in ("abc" "de") 文 字 列 連 結 左 右 の 文 字 列 をつなぐ z="abc" "DEFG" "HI" 文 字 列 比 較 : 比 較 演 算 子 と 共 に 用 いる 左 右 の 文 字 列 の 長 さを 短 い 方 に 揃 えてから 比 較 する a="12345"; b="123"; if a=:b ( 真 ) [ 別 表 5] 関 数 一 覧 分 類 関 数 名 意 味 例 三 角 ARCOS アークコサイン y=arcos(x); ARSIN アークサイン y=arsin(x); 108
ATAN アークタンジェント y=atan(x); COS コサイン y=cos(x); COSH ハイパボリックコサイン y=cosh(x); SIN サイン y=sin(x); SINH ハイパボリックサイン y=sinh(x); TAN タンジェント y=tan(x); TANH ハイパボリックタンジェント y=tanh(x); 数 学 ABS 絶 対 値 y=abs(x); EXP 指 数 y=exp(x); LOG 自 然 対 数 ( 底 =e) y=log(x); LOG10 常 用 対 数 ( 底 =10) y=log10(x); LOG2 2を 底 とする 対 数 y=log2(x); MOD 割 り 算 の 余 りを 返 す y=mod(x,100); POW 累 乗 ** 演 算 子 と 同 じ x=pow(100,2); SIGN 符 号 を 返 す s=sign(-156); SQRT 平 方 根 y=sqrt(x); 数 値 丸 め CEIL 整 数 値 に 切 り 上 げ y=ceil(x); FLOOR 整 数 値 に 切 り 捨 て y=floor(x); FUZZ 最 も 近 い 整 数 値 との 差 が1E-12 以 x=fuzz(x); 内 であればその 整 数 値 を 返 す INT 整 数 部 分 を 取 り 出 す x_int=int(x); ROUND 四 捨 五 入 して 指 定 の 桁 位 置 に 丸 め x=round(125.321,0.1); る ROUNDZ 四 捨 五 入 して 指 定 の 桁 位 置 に 丸 め x=roundz(125.321,0.1); る fuzzing 処 理 を 行 わない 統 計 CSS 修 正 済 平 方 和 x=css(5,10,20,16,0,5); CV 変 動 係 数 (% 表 示 ) x=cv(5,10,20,16,0,5); KURTOSIS 尖 度 x=kurtosis(5,10,20,16,0,5); MAX 最 大 値 x=max(5,10,20,16,0,5); MEAN 平 均 値 x=mean(5,10,20,16,0,5); MIN 最 小 値 x=min(5,10,20,16,0,5); N 非 欠 損 値 の 数 を 返 す n=n(1,3,.,5,10); NMISS 欠 損 値 の 数 を 返 す nmiss=nmiss(1,3,.,5,10); RANGE 範 囲 x=range(5,10,20,16,0,5); SKEWNESS 歪 度 x=skewness(5,10,20,16,0,5); STD 標 準 偏 差 x=std(5,10,20,16,0,5); SUM 合 計 x=std(5,10,20,16,0,5); USS 修 正 前 平 方 和 x=uss(5,10,20,16,0,5); VAR 不 偏 分 散 x=var(5,10,20,16,0,5); 配 列 DIM 配 列 の 要 素 数 を 返 す do i=1 to dim(z); HBOUND 定 義 された 配 列 の 最 後 の 要 素 の 参 do i=lbound(arrayname) to hbound(arrayname); 照 番 号 を 返 す LBOUND 定 義 された 配 列 の 最 初 の 要 素 の 参 do i=lbound(arrayname) to hbound(arrayname); 照 番 号 を 返 す 日 付 と 時 間 DATE 今 日 の 日 付 を 返 す(1960 年 1 月 1 日 today=date(); を 起 点 とした 経 過 日 数 ) TODAYと 同 じ DATEJUL ジュリアン 日 付 値 表 示 から 標 準 の d=datejul(2008366); 日 付 値 に 変 換 DATEPART 日 時 値 から 日 付 値 部 分 を 取 り 出 す date=datepart("01jan2008:12:10:00"dt); DATETIME 現 在 の 日 時 値 を 返 す(1960 年 1 月 1 now=datetime(); 日 を 起 点 とした 経 過 秒 数 ) DAY 日 付 値 または 日 時 値 から 日 部 分 を day=day("10aug2008"d); 取 り 出 す DHMS 日 付 時 分 秒 から 日 時 値 を 作 成 val=dhms("10aug2008"d,12,10,30); HMS 時 分 秒 から 時 間 値 を 作 成 time=hms(12,0,0); HOUR 時 間 値 または 日 時 値 から 時 間 部 分 h=hour("01jan2008:12:10:00"dt); を 取 り 出 す INTCK 開 始 時 点 から 終 了 時 点 までの 経 過 keika_month=intck("month","10jan2008"d,"25aug2008"d); 109
時 間 をさまざまな 時 間 単 位 で 計 算 INTNX 指 定 の 時 間 経 過 後 の 時 点 を 返 す after=intnx("month","10jan2008"d,3,"end"); JULDATE 日 付 値 を5 桁 のジュリアン 日 付 値 形 juldate=juldate("01jan2008"d); 式 (yyddd)に 変 換 JULDATE7 日 付 値 を7 桁 のジュリアン 日 付 値 形 juldate=juldate7("01jan2008"d); 式 (yyyyddd)に 変 換 MDY 月 日 年 から 日 付 値 を 作 成 date1=mdy(12,31,2007); MINUTE 時 間 値 または 日 時 値 から 分 部 分 を m=minute("01jan2008:12:10:00"dt); 取 り 出 す MONTH 日 付 値 または 日 時 値 から 分 部 分 を month=month("01jan2008:12:10:00"dt); 取 り 出 す QTR 日 付 値 または 日 時 値 から 四 半 期 部 qtr=qtr("10aug2008"d); 分 を 取 り 出 す SECOND 時 間 値 または 日 時 値 から 秒 部 分 を s=second("01jan2008:12:10:00"dt); 取 り 出 す TIME 現 在 の 時 間 値 を 返 す now=time(); TIMEPART 日 時 値 から 時 間 部 分 を 取 り 出 す time=timepart("01jan2008:12:10:00"dt); TODAY 今 日 の 日 付 を 返 す(1960 年 1 月 1 日 today=today(); を 起 点 とした 経 過 日 数 ) DATEの 別 名 WEEKDAY 日 付 値 または 日 時 値 から 曜 日 を 取 week=weekday("10aug2008"d); り 出 す YEAR 日 付 値 または 日 時 値 から 年 部 分 を year=year("10aug2008"d); 取 り 出 す YYQ 年 四 半 期 から 日 付 値 を 作 成 yyq=yyq(2008,1); ビット 演 算 BAND ビットのAND x=band(9fx,11x); BLSHIFT ビットを 左 シフトする x=blshift(01x,1); BNOT ビットのNOT x=bnot(01x); BOR ビットのOR x=bor(9fx,90x); BRSHIFT ビットを 右 シフトする x=brshift(01x,31); BXOR ビットのXOR bxor(01x,55x); マクロ CALL DATAステップの 中 から 実 行 ルーテ if x=1 then call execute("proc print;"); EXECUTE ィンを 呼 び 出 す CALL SYMDEL グローバルマクロ 変 数 を 削 除 ( 動 かない) CALL SYMPUT DATAステップ 変 数 値 をマクロ 変 数 call symput("mvar",char); 値 に 割 り 当 てる SYMGET マクロ 変 数 値 をDATAステップ 変 数 c=symget("c"); 値 に 変 換 文 字 BYTE ASCII 文 字 を 返 す RANKの 逆 char=byte(40x); CAT 文 字 列 を 連 結 する List=cat(a,b): CATS 前 後 のブランクを 詰 めてから 文 字 List_space=cats(a,b); 列 を 連 結 する CATT 後 ろのブランクを 詰 めてから 文 字 列 List_trim=catt(a,b); を 連 結 する COMPBL 連 続 するブランクを1 個 に 圧 縮 する char=compbl(a " " b); COMPRESS 指 定 の 文 字 (デフォルトはブランク) char=compress(a b); を 除 外 する CONTAINS 指 定 の 部 分 文 字 列 の 有 無 をチェッ check=contains(c,"abc"); クする INDEX 文 字 値 から 指 定 の 文 字 列 の 開 始 position=index("abcabdefgh","bde"); 位 置 を 返 す INDEXC 文 字 値 から 指 定 のいずれかの 文 字 position=indexc("abcabdefgh","bde"); の 開 始 位 置 を 返 す INDEXW 文 字 値 から 指 定 のワードの 開 始 位 position=indexw("abc,abde,fgh","abde",","); 置 を 返 す LEFT 文 字 値 を 左 詰 する char=left(" abc "); LENGTH 文 字 値 の 長 さを 返 す len=length(compress(x)); LIKE 正 規 表 現 のあいまい 検 索 if like(c1,"_abc%") then put "OK"; LOWCASE 小 文 字 変 換 low=lowcase("abc"); 110
MAXC ブランクを 除 く 最 大 の 文 字 値 maxchar=maxc("z1","abc"); MINC ブランクを 除 く 最 小 の 文 字 値 minchar=minc("z1","abc"); PROPCASE 特 殊 文 字 をデリミタとして 語 単 位 に c=propcase("new/software@world","/@ "); 先 頭 は 大 文 字 化 残 りの 文 字 は 小 文 字 化 する RANK 1 文 字 値 のシーケンス 番 号 を 返 す seq=rank("z"); BYTEの 逆 REPEAT 1 文 字 の 繰 り 返 し 文 字 列 を 作 成 char=repeat("z",10); REVERSE 文 字 値 を 逆 順 に 並 べ 替 える rev_c=reverse(c); RIGHT 文 字 値 を 右 詰 する char=right(" abc "); SCAN 区 切 り 文 字 で 区 切 られたn 番 目 の c=scan("new/software@world",2,"/@ "); 文 字 列 を 抽 出 SUBSTR 部 分 文 字 列 の 抽 出 c=substr("abcdefg",3,2); TRANSLATE 特 定 の 文 字 を 別 の 文 字 に 変 換 する new=translate("abcdefgfcded","150","ceg"); TRANWRD 特 定 の 文 字 列 を 別 の 文 字 列 に 変 new=tranwrd("abcdefgfcded","cd","99"); 換 する TRIM 文 字 値 の 後 ろ 側 のブランクを 削 除 c=trim(a) trim(b); する TRIMN 欠 損 値 に 対 して 長 さ0の 文 字 値 を 返 c=trimn(a); す 以 外 はTRIMと 同 じ UPCASE 大 文 字 変 換 up=upcase("abc"); VERIFY 文 字 値 が 指 定 の 文 字 のみ 含 むか chk=verify("abcdefgfcded","abcdefg"); どうかをチェック DBCS 関 数 KCOMPRESS 指 定 の 文 字 (デフォルトはブランク) char=kcompress(a b); を 除 外 する KINDEX 文 字 値 から 指 定 の 文 字 列 の 開 始 position=kindex("abcあいうefgh","うe"); 位 置 を 返 す KINDEXC 文 字 値 から 指 定 のいずれかの 文 字 position=kindexc("abcあいうefgh","bうe"); の 開 始 位 置 を 返 す KLEFT 前 にある 全 角 と 半 角 のブランク 文 char=kleft(" abc "); 字 を 削 除 して 文 字 列 を 左 詰 する KLENGTH 文 字 値 の 長 さを 返 す len=klength(kcompress(x)); KLOWCASE 小 文 字 変 換 low=klowcase(a); KREVERSE 文 字 値 を 逆 順 に 並 べ 替 える rev_c=kreverse(c); KRIGHT 後 にある 全 角 と 半 角 のブランク 文 char=kright(" abc "); 字 を 削 除 して 文 字 値 を 右 詰 する KSCAN 区 切 り 文 字 で 区 切 られたn 番 目 の c=kscan("new/ソフト@world",2,"/@ "); 文 字 列 を 抽 出 KSUBSTR 部 分 文 字 列 の 抽 出 c=ksubstr("abcあいうdefg",4,3); KTRANSLATE 特 定 の 文 字 を 別 の 文 字 に 変 換 する new=ktranslate("abcあいうgfcded","150","あいう"); KTRIM 文 字 値 の 後 ろ 側 の 全 角 および 半 角 c=ktrim(a) trim(b); のブランクを 削 除 する KUPCASE 大 文 字 変 換 up=kupcase(a); KVERIFY 文 字 値 が 指 定 の 文 字 のみ 含 むか chk=kverify("abcdeabあいうfgfcded","abcdefあいう"); どうかをチェック 乱 数 CALL RANCAU コーシー 乱 数 (シードの 詳 細 制 御 可 call rancau(seed,x); 能 ) CALL RANNOR 正 規 乱 数 (シードの 詳 細 制 御 可 能 ) call rannor(seed,x); CALL RANUNI 一 様 乱 数 (シードの 詳 細 制 御 可 能 ) call ranuni(seed,x); RANCAU コーシー 乱 数 x=rancau(seed); RANNOR 正 規 乱 数 x=rannor(seed); RANUNI 一 様 乱 数 UNIFORMと 同 じ x=ranuni(seed); UNIFORM 一 様 乱 数 RANUNIの 別 名 x=uniform(seed); データセット 操 ATTRC 文 字 型 属 性 の 値 をとる dslabel=attrc(dsid,"label"): 作 ATTRN 数 値 型 属 性 の 値 をとる nobs=attrn(dsid,"nobs"); CLOSE データセットをクローズ dsid=close("work.a"); EXIST データセットやカタログが 存 在 する かどうかをチェック rc=exist(work.a,data); 111
FETCH オープンしたデータセットのオブザ rc=fetch(dsid); ベーション 読 み 取 りポインタを 次 の オブザベーションに 移 動 する FETCHOBS オープンしたデータセットのオブザ rc=fetchobs(dsid,5,abs); ベーション 読 み 取 りポインタを 指 定 のオブザベーションに 移 動 する GETVARC FETCHされているオブザベーション cval=getvarc(dsid,varnum(dsid,"varc"); の 文 字 変 数 値 を 読 み 取 る GETVARN FETCHされているオブザベーション xval=getvarn(dsid,varnum(dsid,"varx"); の 数 値 変 数 値 を 読 み 取 る LIBREF ライブラリ 参 照 名 の 存 在 をチェック rc=libref("work"); ( 値 0が 返 ると 存 在 を 意 味 する) OPEN データセットをオープン dsid=open("work.a"); PATHNAME データライブラリ 参 照 名 またはファ path1=pathname("work"); イル 参 照 名 の 物 理 パスを 返 す SYSMSG ファイルアクセス 時 のエラーメッセ msg=sysmsg(); ージまたは 警 告 メッセージを 獲 得 VARFMT 変 数 に 定 義 されているフォーマット fmt=varfmt(dsid,varnum(dsid,"a")); 名 を 返 す VARINFMT 変 数 に 定 義 されているインフォーマ infmt=varinfmt(dsid,varnum(dsid,"a")); ット 名 を 返 す VARLABEL 変 数 に 定 義 されているラベル 名 を label=varlabel(dsid,varnum(dsid,"a")); 返 す VARLEN 変 数 に 定 義 されている 長 さを 返 す len=varlen(dsid,varnum(dsid,"a")); VARNAME 変 数 に 定 義 されている 変 数 名 を 返 name1=varname(dsid,1); す VARNUM 変 数 名 の 定 義 されている 番 号 を 返 num=varnum(dsid,"a")); す VARTYPE 変 数 に 定 義 されているタイプを 返 す type=vartype(dsid,varnum(dsid,"a")); その 他 CALL SYSTEM OSコマンドを 呼 び 出 す call system("dir c:\"); CHOOSEC 文 字 列 リストから 指 定 の 番 号 の 文 a=choosec(2,"abc","de","fgh"); 字 列 を 抽 出 する CHOOSEN 数 値 リストから 指 定 の 番 号 の 数 値 x=choosen(5,120,35,11,16,280); を 抽 出 する DIF nオブザベーション 前 の 値 との 差 を d2=dif2(x); とる GETOPTION オプション 設 定 値 を 返 す ls=getoption("linesize"); INPUT インフォーマットを 用 いて 値 を 変 換 num=input("100",3.); LAG nオブザベーション 前 の 値 を 返 す l2=lag2(x); MISSING 欠 損 値 かどうかをチェック if missing(x) then put "MISSING VALUE"; PUT フォーマットを 用 いて 値 を 変 換 char=put(100,3.); SLEEP 実 行 を 休 止 する sleep=sleep(10,1); SOUNDEX 英 語 のみ 関 係 する 文 字 列 分 類 アル a=soundex("hello"); ゴリズム SOUNDSLIKE 2つの 文 字 列 を 英 語 の 発 音 で 比 較 r=soundslike("hello","helow"); SPEDIS 2つの 文 字 列 のレーベンシュタイン distance=spedis("test","twist"); 距 離 を 返 す SYSPARM SYSPARM=オプション 指 定 値 を 返 sysparm=sysparm(); す SYSPROD そのプロダクトのライセンス 有 無 を prod_chk=sysprod("wps"); チェックする SYSTEM OSコマンドを 呼 び 出 しシステムリタ ーンコードを 返 す rc=system("dir c:\"); [ 別 表 6] フォーマット 一 覧 分 類 フォーマット 名 意 味 数 値 コ ード 変 BINARYw. 数 値 をバイナリコード(0 or 1) で 書 き 出 す w と d の 範 囲 (デ フォルト) 例 1-64 (8) x=256;put x binary10.; 0100000000 結 果 112
換 HEXw. 数 値 を 16 進 数 で 書 き 出 す 1-16 (8) x=512;put x hex8.; 00000200 IBw.d IBRw.d IEEEw.d OCTALw. PDw.d PDJULGw. PDJULIw. PIBw.d PIBRw.d PKw.d RBw.d S370FFw.d S370FIBw.d S370FIBUw.d S370FPDw.d S370FPDUw.d S370FPIBw.d S370FRBw.d S370FZDw.d S370FZDLw.d S370FZDSw.d 数 値 を 整 数 バイナリ 形 式 で 書 き 出 す 数 値 をOS 環 境 下 依 存 の 整 数 バイナリ 形 式 で 書 き 出 す 数 値 を IEEE 浮 動 小 数 点 で 書 き 出 す 数 値 を 8 進 数 表 記 で 書 き 出 す 数 値 をパック 10 進 数 形 式 で 書 き 出 す 数 値 を z/os 上 のパックジュ リアン 日 付 値 yyyydddf の 形 式 で 書 き 出 す 数 値 を z/os 上 の 16 進 パッ クジュリアン 日 付 値 ccyydddf の 形 式 で 書 き 出 す 数 値 をOS 環 境 下 依 存 の 正 の 整 数 バイナリ 形 式 で 書 き 出 す 数 値 を Window OS 環 境 の 正 の 整 数 バイナリ 形 式 で 書 き 出 す 数 値 を 符 号 なしパック 10 進 数 形 式 で 書 き 出 す 数 値 をOSに 依 存 する 実 数 バ イナリ 形 式 で 書 き 出 す 数 値 を z/os 上 の EBCDIC 文 字 形 式 で 書 き 出 す 数 値 を z/os 上 の 整 数 バイ ナリ 形 式 で 書 き 出 す 数 値 を z/os 上 の 符 号 なしバ イナリ 形 式 で 書 き 出 す 数 値 を z/os 上 のパック 10 進 数 形 式 で 書 き 出 す 数 値 を z/os 上 の 符 号 なしパ ック 10 進 数 形 式 で 書 き 出 す 数 値 を z/os 上 の 正 の 整 数 バイナリ 形 式 で 書 き 出 す 数 値 を z/os 上 の 実 数 バイ ナリ 形 式 で 書 き 出 す 数 値 を z/os 上 のゾーン 10 進 数 形 式 で 書 き 出 す 数 値 を z/os 上 の 符 号 つきゾ ーン 10 進 数 形 式 で 書 き 出 す 数 値 を z/os 上 の 符 号 を 分 離 したゾーン 10 進 数 形 式 で 書 き 出 す 1-8 (4) x=put(12345,ib8.);put x $hex16.; 3930000000000000 1-8 (4) x=put(12345,ibr8.);put x $hex16.; 3930000000000000 1-8 (8) x=put(1,ieee8.);put x $hex16.; 3FF0000000000000 1-24 (3) x=123456789012345;put x octal24.; 000000003404420603357571 1-16 (1) x=put(999,pd4.);put x hex8.; 00000999 3-16 (4) 3-16 (4) x=put("31dec2008"d,pdjulg8.);put x $hex16.; x=put("31dec2008"d,pdjuli8.);put x $hex16.; 1-8 (1) x=put(2,pib1.);put x $hex2.; 02 1-8 (1) x=put(2,pib1.);put x $hex2.; 02 1-16 (1) x=put(2,pk1.);put x $hex2.; 02 2-8 (4) x=put(2,rb2.);put x $hex4.; 0040 000000002008366F 000000000108366F 1-32 (12) x=put(1234,s370ff4.);put x $hex8.; F1F2F3F4 1-8 (4) x=put(1234,s370fib4.);put x $hex8.; 000004D2 1-8 (4) x=put(1234,s370fib4.);put x $hex8.; 000004D2 1-16 (1) x=put(1234,s370fpd4.);put x $hex8.; 0001234C 1-16 (1) x=put(1234,s370fpdu4.);put x $hex8.; 0001234F 1-8 (4) x=put(1234,s370fpib4.);put x $hex8.; 000004D2 2-8 (4) x=put(2,s370frb2.);put x $hex4.; 4120 1-32 (8) x=put(1234,s370fzd4.);put x $hex8.; F1F2F3C4 1-32 (8) x=put(1234,s370fzdl6.);put x $hex16.; C0F0F1F2F3F4 2-32 (8) x=put(1234,s370fzds6.);put x $hex16.; 4EF0F1F2F3F4 113
S370FZDTw.d 数 値 を z/os 上 の 符 号 を 分 離 して 後 ろにつけたゾーン 10 進 数 形 式 で 書 き 出 す 2-32 (8) x=put(1234,s370fzdt6.);put x $hex16.; F0F1F2F3F44E S370FZDUw.d 数 値 を z/os 上 の 符 号 なしゾ ーン 10 進 数 形 式 で 書 き 出 す 1-32 (8) x=put(1234,s370fzdu6.);put x $hex16.; F0F0F1F2F3F4 ZDw.d 数 値 を OS 環 境 下 依 存 のゾ ーン 10 進 数 形 式 で 書 き 出 す 1-16 (8) x=put(12.5,zd5.1);put x $hex32.; 3030313245 数 値 編 集 BESTw.d 数 値 を 指 定 の 長 さで 可 能 な 限 り 詳 細 なフォーマットで 書 き 出 す 1-32 (12) x=111111111111111111;put x best12.; 1.1111111E17 COMMAw.d 整 数 部 分 は 3 桁 おきにカンマ を 追 加 し 指 定 の 小 数 点 桁 数 まで 書 き 出 す 1-32 (6) x=1000000;put x comma12.2; 1,000,000.00 COMMAXw.d 整 数 部 分 は 3 桁 おきにピリオ ドを 追 加 し 小 数 点 はカンマ 表 示 し 指 定 の 小 数 点 桁 数 ま で 書 き 出 す 1-32 (6) x=1000000;put x commax12.2; 1.000.000,00 Dw.d 変 動 範 囲 の 大 きな 数 値 に 対 してなるだけ 小 数 点 位 置 を 揃 えて 書 き 出 す 1-32 (12) x=12.518;put x d6.1; 12.52 DOLLARw.d 数 値 を 先 頭 に$ 3 桁 おきにカ ンマを 付 加 して 書 き 出 す 2-32 (6) x=1250.50;put x dollar12.2; $1,250.50 DOLLARXw.d Ew. FLOATw.d 数 値 を 先 頭 に$ 3 桁 おきにピ リオドを 付 加 し 小 数 点 にカン マを 使 って 書 き 出 す 数 値 を 科 学 ( 浮 動 ) 小 数 点 法 で 書 き 出 す 数 値 を 単 精 度 浮 動 小 数 点 で 書 き 出 す 2-32 (6) x=1250.50;put x dollarx12.4; $1.250,5000 7-32 (12) x=123.456789;put x e12.; 1.23457E+02 4-4 (4) x=put(123.456789,float4.);put x $hex8.; E0E9F642 FRACTw. 数 値 を 分 数 表 示 で 書 き 出 す 4-32 (10) x=0.3;put x fract10.; 3/10 NEGPARENw.d NUMXw.d PERCENTw.d PVALUEw.d 数 値 をカンマ 編 集 し かつ 負 の 値 の 場 合 はカッコで 囲 む 数 値 を 小 数 点 記 号 としてカン マを 用 いて 書 き 出 す 数 値 を% 記 号 をつけたパーセ ンテージ 表 現 で 書 き 出 す 数 値 を p 値 ( 帰 無 仮 説 を 誤 っ て 棄 却 してしまう 確 率 ) 表 示 形 式 で 書 き 出 す 1-32 (6) x=-12567.8;put x negparen8.0.; (12,568) 1-32 (12) x=-12567.8;put x numx8.1; -12567,8 4-32 (6) x=0.0512;put x percent6.1; 5.1% 3-32 (6) p=0.0000000001;put p pvalue6.4; <.0001 ROMANw. 数 値 をローマ 数 字 で 書 き 出 す 2-32 (6) x=2008;put x roman12.; MMVIII SSNw. w.d WORDFw. WORDSw. 数 値 を 社 会 保 障 番 号 (Social Security Number) 形 式 に 書 き 出 す 数 値 を 全 体 で w 文 字 少 数 点 以 下 d 桁 の 形 式 で 書 き 出 す 数 値 を 英 語 の 数 の 読 み 方 で 分 数 表 現 つきで 書 き 出 す 数 値 を 英 語 の 数 の 読 み 方 で 書 き 出 す 11-11 (11) 1-32 (1) x=10.091;put x 5.1; 10.1 5-32767 (10) 5-32767 (10) x=12.25;put x wordf64.; twelve and 25/100 x=12.25;put x words64.; twelve and twenty-five hundredths 114
日 付 時 間 Zw.d DATEw. DATEAMPMw.d DATETIMEw.d DAYw. DDMMYYw. DDMMYYBw. DDMMYYCw. DDMMYYDw. DDMMYYNw. DDMMYYPw. DDMMYYSw. 数 値 を 全 体 で w 文 字 少 数 点 以 下 d 桁 の 形 式 で 書 き 出 す 先 頭 の 0 を 書 き 出 す 点 で w.d と 異 なる 日 付 値 を ddmmmyy または ddmmmyyyy の 形 式 で 書 き 出 す 日 時 値 を ddmmmyy:hh:mm:ss.ss AM ま たは ddmmmyy:hh:mm:ss.ss PM の 形 式 で 書 き 出 す 日 時 値 を ddmmmyy:hh:mm:ss.ss の 形 式 で 書 き 出 す 日 付 値 から 日 付 部 分 を 取 り 出 し dd の 形 式 で 書 き 出 す 日 付 値 を ddmmyy または ddmmyyyy または dd/mm/yy または dd/mm/yyyy の 形 式 で 書 き 出 す 日 付 値 を dd mm yy または dd mm yyyy の 形 式 で 書 き 出 す 日 付 値 を dd:mm:yy または dd:mm:yyyy の 形 式 で 書 き 出 す 日 付 値 を dd-mm-yy または dd-mm-yyyy の 形 式 で 書 き 出 す 日 付 値 を ddmmyy または ddmmyyyy の 形 式 で 書 き 出 す 日 付 値 を dd.mm.yy または dd.mm.yyyy の 形 式 で 書 き 出 す 日 付 値 を dd/mm/yy または dd/mm/yyyy の 形 式 で 書 き 出 す DOWNAMEw. 日 付 値 から 曜 日 を 書 き 出 す 1-32 (9) DTDATEw. DTMONYYw. 日 時 値 を ddmmmyy または ddmmmyyyy の 形 式 で 書 き 出 す 日 時 値 を mmmyy または mmmyyyy の 形 式 で 書 き 出 す 1-32 (1) x=10.091;put x z5.1; 010.1 5-9 (7) x=0;put x date9.; 01JAN1960 7-40 (19) x=0;put x dateampm19.; 01JAN60:12:00:00 AM 7-40 (19) x=0;put x datetime19.; 01JAN1960:00:00:00 2-32 (2) x=0;put x day2.; 1 2-10 (8) x=0;put x ddmmyy10.; 01/01/1960 2-10 (8) x=0;put x ddmmyyb10.; 01 01 1960 2-10 (8) x=0;put x ddmmyyc10.; 01:01:1960 2-10 (8) x=0;put x ddmmyyd10.; 01-01-1960 2-8 (8) x=0;put x ddmmyyn8.; 01011960 2-10 (8) x=0;put x ddmmyyp10.; 01.01.1960 2-10 (8) x=0;put x ddmmyys10.; 01/01/1960 5-9 (7) 5-7 (7) date="01jan2008"d;put date downame9.; x="01jan1960:00:00:00"dt;put x dtdate9.; x="01jan1960:00:00:00"dt;put x dtmonyy7.; Tuesday 01JAN1960 JAN1960 DTWKDATXw. 日 時 値 を day-of week, dd name-of month yy または day-of week, dd name-of month yyyy の 形 式 で 書 き 出 す 3-37 (29) x="01jan1960:00:00:00"dt;put x dtwkdatx29.; 1960 Friday, 1 January DTYEARw. 日 時 値 を yy または yyyy の 形 式 で 書 き 出 す 2-4 (4) x="01jan1960:00:00:00"dt;put x dtyear4.; 1960 DTYYQCw. HHMMw.d 日 時 値 を yy:q または yyyy:q の 形 式 で 書 き 出 す 時 間 値 を hh:mm.mm の 形 式 で 書 き 出 す 4-6 (4) x="01jan1960:00:00:00"dt;put x dtyyqc4.; 60:1 2-20 (5) x=60;put x hhmm.; 0:01 115
HOURw.d JULDAYw. JULIANw. MMDDYYw. MMDDYYBw. MMDDYYCw. MMDDYYDw. MMDDYYNw. MMDDYYPw. MMDDYYSw. MMSSw.d MMYYw. MMYYCw. MMYYDw. MMYYNw. MMYYPw. MMYYSw. 時 間 値 を hh.hh の 形 式 で 書 き 出 す 日 付 値 からジュリアン 日 付 値 の 日 付 部 分 ddd を 書 き 出 す 日 付 値 をジュリアン 日 付 値 yyddd または yyyyddd の 形 式 で 書 き 出 す 日 付 値 を mmddyy, mmddyyyy, mm/dd/yy また は mm/dd/yyyy の 形 式 で 書 き 出 す 日 付 値 を mm dd yy または mm dd yyyy の 形 式 で 書 き 出 す 日 付 値 を mm:dd:yy または mm:dd:yyyy の 形 式 で 書 き 出 す 日 付 値 を mm-dd-yy または mm-dd-yyyy の 形 式 で 書 き 出 す 日 付 値 を mmddyy または mmddyyyy の 形 式 で 書 き 出 す 日 付 値 を mm.dd.yy または mm.dd.yyyy の 形 式 で 書 き 出 す 日 付 値 を mm/dd/yy または mm/dd/yyyy の 形 式 で 書 き 出 す 時 間 値 を mm:ss.ss の 形 式 で 書 き 出 す 日 付 値 を mmmyy または mmmyyyy の 形 式 で 書 き 出 す 日 付 値 を mm:yy または mm:yyyy の 形 式 で 書 き 出 す 日 付 値 を mm-yy または mm-yyyy の 形 式 で 書 き 出 す 日 付 値 を mmyy または mmyyyy の 形 式 で 書 き 出 す 日 付 値 を mm.yy または mm.yyyy の 形 式 で 書 き 出 す 日 付 値 を mm/yy または mm/yyyy の 形 式 で 書 き 出 す 2-20 (2) x=3600;put x hour2.; 1 3-32 (3) x="31dec2008"d;put x julday3.; 366 5-7 (5) x="31dec2008"d;put x julian5.; 08366 2-10 (8) x="31dec2008"d;put x mmddyy10.; 12/31/2008 2-10 (8) x="31dec2008"d;put x mmddyyb10.; 12 31 2008 2-10 (8) x="31dec2008"d;put x mmddyyc10.; 12:31:2008 2-10 (8) x="31dec2008"d;put x mmddyyd10.; 12-31-2008 2-8 (8) x="31dec2008"d;put x mmddyyn8.; 12312008 2-10 (8) x="31dec2008"d;put x mmddyyp10.; 12.31.2008 2-10 (8) x="31dec2008"d;put x mmddyys10.; 12/31/2008 2-20 (5) x="01:10:30"t;put x mmss8.; 70:30 5-32 (7) x="31dec2008"d;put x mmyy7.; 12M2008 5-32 (7) x="31dec2008"d;put x mmyyc7.; 12:2008 5-32 (7) x="31dec2008"d;put x mmyyd7.; 12-2008 4-32 (6) x="31dec2008"d;put x mmyyn6.; 122008 5-32 (7) x="31dec2008"d;put x mmyyp7.; 12.2008 5-32 (7) x="31dec2008"d;put x mmyys7.; 12/2008 MONNAMEw. 日 付 値 から 月 名 を 書 き 出 す 1-32 (9) x="31dec2008"d;put x monname9.; December MONTHw. MONYYw. QTRw. QTRRw. 日 付 値 から 月 部 分 を 取 り 出 し mm の 形 式 で 書 き 出 す 日 付 値 を mmmyy または mmmyyyy の 形 式 で 書 き 出 す 日 付 値 を 四 半 期 q 形 式 で 書 き 出 す 日 付 値 を 四 半 期 qr 形 式 で 書 き 出 す 1-32 (9) x="31dec2008"d;put x month2.; 12 5-7 (5) x="31dec2008"d;put x monyy5.; DEC08 1-32 (1) x="31dec2008"d;put x qtr1.; 4 3-32 (3) x="31dec2008"d;put x qtrr3.; IV 116
TIMEw.d TIMEAMPMw.d 時 間 値 または 日 時 値 を hh:mm:ss.ss の 形 式 で 書 き 出 す 時 間 値 または 日 時 値 を hh:mm:ss.ss AM または hh:mm:ss.ss PM の 形 式 で 書 き 出 す 2-20 (8) 2-20 (11) x="01jan1960:00:00:00"dt;put x time8.; x="01jan1960:00:00:00"dt;put x timeampm11.; 0:00:00 12:00:00 AM TODw. 日 時 値 から hh:mm:ss.ss の 形 式 で 時 間 部 分 のみを 書 き 出 す 2-20 (8) x="01jan1960:00:00:00"dt;put x tod8.; 00:00:00 WEEKDATEw. WEEKDATXw. WEEKDAYw. WORDDATEw. WORDDATXw. YEARw. YYMMw. YYMMCw. YYMMDw. YYMMNw. YYMMPw. YYMMSw. YYMMDDw. YYMMDDBw. YYMMDDCw. YYMMDDDw. YYMMDDNw. 日 付 値 を 曜 日, 月 名 dd, yy または 曜 日, 月 名 dd, yyyy の 形 式 で 書 き 出 す 日 付 値 を 曜 日, dd 月 名 yy または 曜 日, dd 月 名 yyyy の 形 式 で 書 き 出 す 日 付 値 を 曜 日 を 表 す 整 数 で 書 き 出 す 日 付 値 を 月 名 dd, yy また は 月 名 dd, yyyy の 形 式 で 書 き 出 す 日 付 値 を dd 月 名 yy また は dd 月 名 yyyy の 形 式 で 書 き 出 す 日 付 値 から 年 部 分 を 取 り 出 し yy または yyyy の 形 式 で 書 き 出 す 日 付 値 を yymmm または yyyymmm の 形 式 で 書 き 出 す 日 付 値 を yy:mm または yyyy:mm の 形 式 で 書 き 出 す 日 付 値 を yy-mm または yyyy-mm の 形 式 で 書 き 出 す 日 付 値 を yymm または yyyymm の 形 式 で 書 き 出 す 日 付 値 を yy.mm または yyyy.mm の 形 式 で 書 き 出 す 日 付 値 を yy/mm または yyyy/mm の 形 式 で 書 き 出 す 日 付 値 を yymmdd, yyyymmdd, yy/mm/dd また は yyyy/mm/dd の 形 式 で 書 き 出 す 日 付 値 を yy mm dd または yyyy mm dd の 形 式 で 書 き 出 す 日 付 値 を yy:mm:dd または yyyy:mm:dd の 形 式 で 書 き 出 す 日 付 値 を yy-mm-dd または yyyy-mm-dd の 形 式 で 書 き 出 す 日 付 値 を yymmdd または yyyymmdd の 形 式 で 書 き 出 す 3-37 (29) x="31dec2008"d;put x weekdate3.; Wed 3-37 (29) x="31dec2008"d;put x weekdatx29.; 1-32 (1) x="31dec2008"d;put x weekday1.; 4 Wednesday, 31 December 2008 3-32 (18) x="31dec2008"d;put x worddate18.; December 31, 2008 3-32 (18) x="31dec2008"d;put x worddatx18.; 31 December 2008 2-32 (4) x="31dec2008"d;put x year4.; 2008 5-32 (7) x="31dec2008"d;put x yymm7.; 2008M12 5-32 (7) x="31dec2008"d;put x yymmc7.; 2008:12 5-32 (7) x="31dec2008"d;put x yymmd7.; 2008-12 4-32 (6) x="31dec2008"d;put x yymmn6.; 200812 5-32 (7) x="31dec2008"d;put x yymmp7.; 2008.12 5-32 (7) x="31dec2008"d;put x yymms7.; 2008/12 2-10 (8) x="31dec2008"d;put x yymmdd10.; 2008-12-31 2-10 (8) x="31dec2008"d;put x yymmddb10.; 2008 12 31 2-10 (8) x="31dec2008"d;put x yymmddc10.; 2008:12:31 2-10 (8) x="31dec2008"d;put x yymmddd10.; 2008-12-31 2-8 (8) x="31dec2008"d;put x yymmddn8.; 20081231 117
YYMMDDPw. YYMMDDSw. YYMONw. YYQw. YYQCw. YYQDw. YYQNw. YYQPw. YYQSw. YYQRw. YYQRCw. YYQRDw. YYQRNw. YYQRPw. YYQRSw. 日 付 値 を yy.mm.dd または yyyy.mm.dd の 形 式 で 書 き 出 す 日 付 値 を yy/mm/dd または yyyy/mm/dd の 形 式 で 書 き 出 す 日 付 値 を yymmm または yyyymmm の 形 式 で 書 き 出 す 日 付 値 を yyqq または yyyyqq の 形 式 で 書 き 出 す 日 付 値 を yy:q または yyyy:q の 形 式 で 書 き 出 す 日 付 値 を yy-q または yyyy-q の 形 式 で 書 き 出 す 日 付 値 を yyq または yyyyq の 形 式 で 書 き 出 す 日 付 値 を yy.q または yyyy.q の 形 式 で 書 き 出 す 日 付 値 を yy/q または yyyy/q の 形 式 で 書 き 出 す 日 付 値 を yyqqr または yyyyqqr の 形 式 で 書 き 出 す 日 付 値 を yy:qr または yyyy:qr の 形 式 で 書 き 出 す 日 付 値 を yy-qr または yyyy-qr の 形 式 で 書 き 出 す 日 付 値 を yyqr または yyyyqr の 形 式 で 書 き 出 す 日 付 値 を yy.qr または yyyy.qr の 形 式 で 書 き 出 す 日 付 値 を yy/qr または yyyy/qr の 形 式 で 書 き 出 す 2-10 (8) x="31dec2008"d;put x yymmddp10.; 2008.12.31 2-10 (8) x="31dec2008"d;put x yymmdds10.; 2008/12/31 5-32 (7) x="31dec2008"d;put x yymon7.; 2008DEC 4-32 (6) x="31dec2008"d;put x yyq6.; 2008Q4 4-32 (6) x="31dec2008"d;put x yyqc6.; 2008:4 4-32 (6) x="31dec2008"d;put x yyqd6.; 2008-4 3-32 (5) x="31dec2008"d;put x yyqn6.; 20084 4-32 (6) x="31dec2008"d;put x yyqp6.; 2008.4 4-32 (6) x="31dec2008"d;put x yyqs6.; 2008/4 6-32 (8) x="31dec2008"d;put x yyqr6.; 08QIV 6-32 (8) x="31dec2008"d;put x yyqrc6.; 08:IV 6-32 (8) x="31dec2008"d;put x yyqrd6.; 08-IV 5-32 (7) x="31dec2008"d;put x yyqrn.; 2008IV 6-32 (8) x="31dec2008"d;put x yyqrp6.; 08.IV 6-32 (8) x="31dec2008"d;put x yyqrs6.; 08/IV 文 字 編 集 $CHARw. 文 字 列 を 先 頭 のブランクは 詰 めずにそのまま 書 き 出 す 1-32767 (8) c=" " put(" ABC ",$char7.) " ";put c; ABC $Fw. 文 字 列 を 文 字 列 として 書 き 出 す $w.と 同 じ 1-32767 (1) c="abc";put c $F3.; ABC $QUOTEw. 文 字 列 をダブルクオテーショ ンで 囲 んで 書 き 出 す 2-32767 (8) c="abc";put c $quote5.; "ABC" $REVERJw. 文 字 列 を 逆 順 に 書 き 出 す 先 頭 および 後 ろのブランクは 取 り 除 かない 1-32767 (1) c=put(" ABC ",$char7.);put " " c $reverj7. " "; CBA $REVERSw. 文 字 列 を 逆 順 に 書 き 出 す 先 頭 のブランクは 取 り 除 かない が 後 ろは 除 く 1-32767 (1) c=put(" ABC ",$char7.);put " " c $revers7. " "; CBA $UPCASEw. $w. 文 字 列 を 大 文 字 化 して 書 き 出 す 文 字 列 を 文 字 列 として 書 き 出 す $Fw.と 同 じ 1-32767 (1) 1-32767 (1) c="abc";put c $upcase3.; c="abc";put c $3.; ABC ABC 118
文 字 コ ード 変 換 $ASCIIw. $BINARYw. $EBCDICw. $HEXw. $OCTALw. 文 字 列 を ASCII コード 文 字 で 書 き 出 す ただし PC 環 境 で は$CHARw.と 同 じ 文 字 列 をバイナリコード(0 or 1)で 書 き 出 す 文 字 列 を EBCDIC コード 文 字 で 書 き 出 す 文 字 列 を 16 進 コードで 書 き 出 す 文 字 列 を 8 進 コードで 書 き 出 す 1-32767 (1) 1-32767 (1) 1-32767 (1) 1-32767 (1) 注 : 数 値 フォーマットに 共 通 : w.d の d を 指 定 した 場 合 小 数 点 以 下 d 桁 を 表 示 する c=put("abc",$ascii3.);put c $hex6.; 414243 c="abc";put c $binary24.; 010000010100001001000011 c=put("abc",$ebcdic3.);put c $hex6.; C1C2C3 c="abc";put c $hex6.; 414243 1-24 (3) c="abc";put c $octal6.; 101102 [ 別 表 7] インフォーマット 一 覧 分 類 フォーマット 名 意 味 数 値 BESTw.d BITSw.d COMMAw.d COMMAXw.d DOLLARw.d DOLLARXw.d Ew. FLOATw.d HEXw. IBw.d 数 値 を 読 み 込 む 1 個 のピリ オドは 欠 損 値 とみなす 文 字 列 をビット 列 として 読 み 込 み 対 応 する 数 値 に 変 換 す る 数 字 とピリオド そして 先 頭 の プラス 記 号 とマイナス 記 号 以 外 のカンマ ブランク ダッシ ュ ドル 記 号 % 記 号 右 カッコ を 除 去 して 読 み 込 む 先 頭 の 左 カッコはマイナス 記 号 に 変 換 する 数 字 とカンマ そして 先 頭 の プラス 記 号 とマイナス 記 号 以 外 のピリオド ブランク ダッ シュ ドル 記 号 % 記 号 右 カッ コを 除 去 して 読 み 込 む 先 頭 の 左 カッコはマイナス 記 号 に 変 換 する 数 字 とピリオド そして 先 頭 の プラス 記 号 とマイナス 記 号 以 外 のカンマ ブランク ダッシ ュ ドル 記 号 % 記 号 右 カッコ を 除 去 して 読 み 込 む 先 頭 の 左 カッコはマイナス 記 号 に 変 換 する 数 字 とカンマ そして 先 頭 の プラス 記 号 とマイナス 記 号 以 外 のピリオド ブランク ダッ シュ ドル 記 号 % 記 号 右 カッ コを 除 去 して 読 み 込 む 先 頭 の 左 カッコはマイナス 記 号 に 変 換 する 科 学 ( 浮 動 ) 小 数 点 法 で 書 か れた 数 値 を 読 み 込 む 4 バイトのバイナリ 浮 動 小 数 点 形 式 で 書 かれた 数 値 を 読 み 込 む 16 進 数 を 表 す 文 字 列 を 数 値 として 読 み 込 む Window 環 境 下 の 整 数 バイナ リ 形 式 で 書 かれた 値 を 読 み 込 む w と d の 範 囲 (デ フォルト) 例 結 果 1-32 (1) x=input("1.1111111e17",best12.);put x; 1.1111111E17 1-64 (1) x=input("a",bits8.);put x; 65 1-32 (1) x=input("-$1,234.5",comma12.);put x; -1234.5 1-32 (1) x=input("-$1.234,5",commax12.);put x; -1234.5 1-32 (1) x=input("$1,250.50",dollar12.);put x; 1250.5 1-32 (1) x=input("$1.250,50",dollarx12.);put x; 1250.5 1-32 (1) x=input("1.23457e+02",e12.);put x; 123.457 4-4 (4) x=input("e0e9f642"x,float4.);put x; 123.45678711 1-16 (8) x=input("ffff",hex4.);put x; 65535 1-8 (4) x=input("39300000"x,ibr8.);put x; 12345 119
日 付 時 間 IBRw.d PERCENTw. PIBw.d PIBRw.d PKw.d RBw.d w.d PDw.d DATEw. DATETIMEw DDMMYYw. JULIANw. MMDDYYw. MONYYw. TIMEw. YYMMDDw. YYMMNw. OS 環 境 下 依 存 の 整 数 バイナ リ 形 式 で 書 かれた 値 を 読 み 込 む 数 値 をパーセントとして 読 み 込 む ピリオド 以 外 のカンマ ブランク ダッシュ パーセント 記 号 と 右 カッコを 無 視 し 先 頭 の 左 カッコはマイナス 記 号 に 変 換 する パーセント 記 号 は 除 去 され 値 は 100 で 割 る OS 環 境 依 存 の 正 の 整 数 バイ ナリ 形 式 の 数 値 を 読 み 込 む Window OS 環 境 下 の 正 の 整 数 バイナリ 形 式 の 数 値 を 読 み 込 む 符 号 なしパック 10 進 数 形 式 の 数 値 を 読 み 込 む OS 環 境 に 依 存 する 実 数 バイ ナリ 形 式 の 数 値 を 読 み 込 む 全 体 で w 文 字 少 数 点 以 下 d 桁 の 形 式 で 書 かれた 数 値 を 読 み 込 む ピリオド1 個 (.)は 欠 損 値 として 読 み 込 む パック 10 進 数 形 式 で 書 かれ た 値 を 読 み 込 む ddmmmyy または ddmmmyyyy の 形 式 で 書 か れた 値 を 日 付 値 として 読 み 込 む ddmmmyy:hh:mm:ss.ss また は ddmmmyyyy:hh:mm:ss.ss の 形 式 で 書 かれた 値 を 日 時 値 として 読 み 込 む ddmmyy, ddmmyyyy の 形 式 または dd/mm/yy, dd/mm/yyyy などの 区 切 り 文 字 付 きの 形 式 で 書 かれた 値 を 日 付 値 として 読 み 込 む ジュリアン 日 付 値 yyddd ま たは yyyyddd の 形 式 で 書 か れた 値 を 日 付 値 として 読 み 込 む mmddyy, mmddyyyy の 形 式 または mm/dd/yy, mm/dd/yyyy などの 区 切 り 文 字 付 き 形 式 で 書 かれた 文 字 列 を 日 付 値 として 読 み 込 む mmmyy, mmmyyyy の 形 式 または mmm/yy, mmn/yyyy などの 区 切 り 文 字 付 き 形 式 で 書 かれた 文 字 列 を 日 付 値 とし て 読 み 込 む hh:mm:ss.ss の 形 式 で 書 かれ た 数 値 を 時 間 値 として 読 み 込 む yymmdd, yyyymmdd または yycmmcdd, yyyycmmcdd(c は /などの 区 切 り 文 字 ) の 形 式 で 書 かれた 値 を 日 付 値 として 読 み 込 む yymm または yyyymm の 形 式 で 書 かれた 値 を 日 付 値 とし 1-8 (4) x=input("39300000"x,ibr8.);put x; 12345 1-32 (6) x=input("(5.12%",percent6.);put x; -0.0512 1-8 (1) x=input("02"x,pib2.);put x; 2 1-8 (1) x=input("02"x,pib2.);put x; 2 1-16 (1) x=input("02"x,pk2.);put x; 2 2-8 (4) x=input("0040"x,rb4.);put x; 2 1-32 (1) x=input("10.091",6.3);put x; 10.091 1-16 (1) x=input("00000999"x,pd8.);put x; 999 7-32 (7) x=input("01jan1960",date9.);put x; 0 13-40 (18) x=input("01jan1960:00:01:00",datetime18.);put x; 60 6-32 (6) x=input("10/01/1960",ddmmyy10.);put x; 9 5-32 (5) x=input("08366",julian5.);put x; 17897 2-10 (8) x=input("12/31/2008",mmddyy10.);put x; 17897 5-32 (5) x=input("dec08",monyy5.);put x; 17867 5-32 (8) x=input("12:10:30",time8.);put x; 43830 6-32 (6) x=input("2008-12-31",yymmdd10.);put x; 17897 4-6 (6) x=input("200812",yymmn6.);put x; 17867 120
て 読 み 込 む 文 字 z/os 数 値 $CHARw. $CHARZBw. $UPCASEw. $w. $ASCIIw. $BINARYw. $EBCDICw. $HEXw. $PHEXw. S370FFw.d S370FIBw.d S370FIBUw.d S370FPDw.d S370FPDUw.d S370FPIBw.d S370FRBw.d S370FZDw.d S370FZDBw.d S370FZDLw.d S370FZDSw.d 文 字 列 を 先 頭 のブランクは 詰 めずにそのまま 読 み 込 む ま た 空 白 付 き 空 白 付 きでない にかかわらず ピリオド1 個 は 欠 損 値 とみなさない 文 字 列 をバイナリゼロはブラ ンクに 変 換 して 読 み 込 む そ の 他 は$CHARw. と 同 じ 文 字 列 を 大 文 字 化 して 読 み 込 む 先 頭 のブランクを 無 視 して 文 字 列 を 読 み 込 む また 空 白 付 き 空 白 付 きでないにかか わらず ピリオド1 個 は 欠 損 値 とみなす ASCII コード 文 字 で 書 かれた 文 字 列 を 読 み 込 む ただし PC 環 境 では$CHARw.と 同 じ バイナリコード(0 or 1)で 書 か れた 文 字 列 を 読 み 込 む EBCDIC コード 文 字 列 を 読 み 込 む 16 進 コードで 書 かれた 文 字 列 を 読 み 込 む パック 16 進 コードで 書 かれた 文 字 列 を 読 み 込 む z/os 環 境 下 の EBCDIC 文 字 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 整 数 バイナリ 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 符 号 なしバイ ナリ 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 のパック 10 進 数 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 符 号 なしパッ ク 10 進 数 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 正 の 整 数 バイ ナリ 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 実 数 バイナリ 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 のゾーン 10 進 数 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 0 はブランク で 表 現 された 符 号 つきゾーン 10 進 数 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 符 号 つきゾー ン 10 進 数 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 符 号 を 分 離 し たゾーン 10 進 数 形 式 で 書 か れた 数 値 を 読 み 込 む 1-32767 (8) 1-32767 (8) 1-32767 (8) 1-32767 (1) 1-32767 (1) 1-32767 (1) 1-32767 (1) 1-32767 (2) 1-32767 (2) c=input(" ABC ",$char10.);put c $char.; c=input("2041420043"x,$charzb10.);put c $char.; c=input("abc",$upcase3.);put c; ABC AB C ABC c=input(" ABC",$6.);put c $char6.; ABC c=input("414243"x,$ascii3.);put c; c=input("010000010100001001000011",$binary24.) ;put c ; c=input("c1c2c3"x,$ebcdic6.);put c $char.; c=input("414243",$hex6.);put c $char.; ABC ABC ABC ABC c=input("414243",$phex6.);put c $char.; 343134 1-32 (12) x=input("f1f2f3f4"x,s370ff8.);put x; 1234 1-8 (4) x=input("000004d2"x,s370fib8.);put x; 1234 1-8 (4) x=input("000004d2"x,s370fib8.);put x; 1234 1-16 (1) x=input("0001234c"x,s370fpd8.);put x; 1234 1-16 (1) x=input("0001234f"x,s370fpdu8.);put x; 1234 1-8 (4) x=input("000004d2"x,s370fpib8.);put x; 1234 2-8 (6) x=input("4120"x,s370frb4.);put x; 2 1-32 (8) x=input("f1f2f3c4"x,s370fzd8.);put x; 1234 1-32 (8) x=input("c0f0f1f2f3f4"x,s370fzdl12.);put x; 1234 1-32 (8) x=input("c0f0f1f2f3f4"x,s370fzdl12.);put x; 1234 2-32 (8) x=input("4ef0f1f2f3f4"x,s370fzds12.);put x; 1234 121
z/os 日 付 時 間 S370FZDTw.d S370FZDUw.d ZDw.d ZDBw.d MSECw. PDJULGw. PDJULIw. PDTIMEw. RMFDURw. RMFSTAMPw. SMFSTAMPw.d TODSTAMPw. TUw. z/os 環 境 下 の 符 号 を 分 離 し て 後 ろにつけたゾーン 10 進 数 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 符 号 なしゾー ン 10 進 数 形 式 で 書 かれた 数 値 を 読 み 込 む OS 環 境 依 存 のゾーン 10 進 数 形 式 ( 最 後 のバイトに 符 号 つきデジタル)で 書 かれた 数 値 を 読 み 込 む OS 環 境 依 存 の0がブランク で 表 現 されているゾーン 10 進 数 形 式 で 書 かれた 数 値 を 読 み 込 む z/os 環 境 下 の 8 バイトマイ クロ 秒 値 を 時 間 値 として 読 み 込 む z/os 環 境 下 のパックジュリア ン 日 付 値 yyyydddf の 形 式 で 書 かれた 値 を 日 付 値 として 読 み 込 む z/os 環 境 下 の 16 進 パックジ ュリアン 日 付 値 ccyydddf の 形 式 で 書 かれた 値 を 日 付 値 と して 読 み 込 む z_os 環 境 下 の RMF や SMF レコードに 見 られる 0hhmmssF 形 式 の 16 進 パッ ク 時 間 値 を 読 み 込 む z_os 環 境 下 の mmsstttf 16 進 形 式 の RMF レコードの 時 間 値 を 読 み 込 む z_os 環 境 下 の 0hhmmssFccyydddF 16 進 形 式 の RMF レコードの 時 間 値 を 読 み 込 む z_os 環 境 下 の hhhhhhhhccyydddf 16 進 形 式 の SMF レコードの 日 時 値 を 読 み 込 む z_os 環 境 下 の 8 バイトバイ ナリ 整 数 形 式 の 時 間 値 (Time Of Day)を 数 値 として 読 み 込 む z_os 環 境 下 の 4 バイトバイ ナリ 整 数 形 式 の 時 間 単 位 (Timer Unit)を 数 値 として 読 み 込 む 2-32 (8) x=input("f0f1f2f3f44e"x,s370fzdt12.);put x; 1234 1-32 (8) x=input("f0f0f1f2f3f4"x,s370fzdu12.);put x; 1234 1-32 (1) 1-32 (1) 1-8 (8) 4-4 (4) x=input(put("31dec2008"d,pdjulg4.),pdjulg4.);put x; 17897 4-4 (4) x=input(put("31dec2008"d,pdjuli4.),pdjuli4.);put x; 17897 4-4 (4) 4-4 (4) 8-8 (8) 8-8 (8) 1-8 (8) 4-4 (4) [ 別 表 8] merge ステートメントによる 2 つのデータセットのマージ 例 ( 例 示 データ) 1 対 n のマージ 例 になっていることに 注 意 A B obs name value1 obs name value2 1 A 11 1 A 111 2 B 21 2 A 112 3 C 31 3 B 221 122
4 B 222 5 B 223 6 D 441 7 D 442 (1) 基 本 的 な merge ステートメント+ by 変 数 の 指 定 (いずれかのデータセットに 含 まれる by 変 数 値 がす べて 抽 出 され 個 々の by 変 数 値 のオブザベーション 数 は 左 右 いずれか 多 い 方 に 合 わせて 出 力 されます) data merge1; merge1 merge A B; Obs name value1 value2 by name; 1 A 11 111 2 A 11 112 3 B 21 221 4 B 21 222 5 B 21 223 6 C 31. 7 D. 441 8 D. 442 (SQL の 完 全 外 部 結 合 を 意 味 します) proc sql; reset print number; select coalesce(a.name, B.name) as name, value1, value2 from A full join B on A.name = B.name; quit; Row name value1 value2 1 A 11 111 2 A 11 112 3 B 21 221 4 B 21 223 5 B 21 222 6 C 31. 7 D. 442 8 D. 441 (2) 左 側 の in 変 数 のみ if 条 件 で 使 用 ( 左 側 に 含 まれる by 変 数 値 のみ 抽 出 され 個 々の by 変 数 値 のオブザ ベーション 数 は 左 右 いずれか 多 い 方 に 合 わせて 出 力 されます) data merge2; merge2 merge A(in=A) B; Obs name value1 value2 by name; 1 A 11 111 if A=1; 2 A 11 112 3 B 21 221 4 B 21 222 5 B 21 223 6 C 31. (SQL の 左 外 部 結 合 を 意 味 します) 123
proc sql; reset print number; select coalesce(a.name, B.name) as name, value1, value2 from A left join B on A.name = B.name; quit; Row name value1 value2 1 A 11 111 2 A 11 112 3 B 21 221 4 B 21 223 5 B 21 222 6 C 31. (3) 右 側 の in 変 数 のみ if 条 件 で 使 用 ( 右 側 に 含 まれる by 変 数 値 のみ 抽 出 され 個 々の by 変 数 値 のオブザ ベーション 数 は 左 右 いずれか 多 い 方 に 合 わせて 出 力 されます) data merge3; merge3 merge A B(in=B); Obs name value1 value2 by name; 1 A 11 111 if B=1; 2 A 11 112 3 B 21 221 4 B 21 222 5 B 21 223 6 D. 441 7 D. 442 (SQL の 右 外 部 結 合 を 意 味 します) proc sql; reset print number; select coalesce(a.name, B.name) as name, value1, value2 from A right join B on A.name = B.name; quit; Row name value1 value2 1 A 11 111 2 A 11 112 3 B 21 221 4 B 21 223 5 B 21 222 6 D. 442 7 D. 441 (4) 左 右 の in 変 数 を AND 条 件 で 結 んで 使 用 ( 左 右 両 方 に 共 通 に 含 まれる by 変 数 値 のみ 抽 出 され 個 々の by 変 数 値 のオブザベーション 数 は 左 右 いずれか 多 い 方 に 合 わせて 出 力 されます) data merge4; merge4 merge A(in=A) B(in=B); Obs name value1 value2 124
by name; 1 A 11 111 if A=1 and B=1; 2 A 11 112 3 B 21 221 4 B 21 222 5 B 21 223 (SQL の 内 部 結 合 を 意 味 します) proc sql; reset print number; select coalesce(a.name, B.name) as name, value1, value2 from A, B where A.name = B.name; quit; Row name value1 value2 1 A 11 111 2 A 11 112 3 B 21 221 4 B 21 222 5 B 21 223 (5) 左 側 の in 変 数 のみ 使 用 し 冒 頭 で in 変 数 をリセット( 左 側 に 含 まれる by 変 数 値 のみ 抽 出 され 個 々 の by 変 数 値 のオブザベーション 数 は 左 側 のオブザベーション 数 に 合 わせて 出 力 されます) data merge5; merge5 A=0; Obs name value1 value2 merge A(in=A) B; 1 A 11 111 by name; 2 B 21 221 if A=1; 3 C 31. (SQL で 書 くと 左 外 部 結 合 した 後 元 の 左 側 の 個 々の Row と 結 合 した 一 番 最 初 の Row のみ 抽 出 する ことを 意 味 します) proc sql; reset print number; create table A1 as select *, monotonic() as s1 from A; select *, monotonic() as s from (select coalesce(a1.name, B.name) as name, value1, value2, s1 from A1 left join B on A1.name = B.name) group by s1 having min(s)=s; quit; Row name value1 value2 s1 s 1 A 11 111 1 1 2 B 21 221 2 3 3 C 31. 3 6 (6) in 変 数 の 使 用 ( 右 側 のみ)し 冒 頭 で in 変 数 をリセット( 右 側 に 含 まれる by 変 数 値 のみ 抽 出 され 125
個 々の by 変 数 値 のオブザベーション 数 は 右 側 のオブザベーション 数 に 合 わせて 出 力 されます) data merge6; merge6 B=0; Obs name value1 value2 merge A B(in=B); 1 A 11 111 by name; 2 A 11 112 if B=1; 3 B 21 221 4 B 21 222 5 B 21 223 6 D. 441 7 D. 442 ( 右 外 部 結 合 した 後 元 の 右 側 の 個 々の Row と 結 合 した 一 番 最 初 の Row のみ 抽 出 する 処 理 を 意 味 しま す) proc sql; reset print number; create table B1 as select *, monotonic() as s2 from B; select *, monotonic() as s from (select coalesce(a.name, B1.name) as name, value1, value2, s2 from A right join B1 on A.name = B1.name) group by s2 having min(s)=s; quit; Row name value1 value2 s2 s 1 A 11 111 1 1 2 A 11 112 2 2 3 B 21 221 3 3 4 B 21 222 4 5 5 B 21 223 5 4 6 D. 441 6 7 7 D. 442 7 6 ( 注 :この 例 では 右 外 部 結 合 結 果 と 同 じになります) (7) 左 右 の in 変 数 を AND 条 件 で 結 んで 使 用 し 冒 頭 で 両 方 の in 変 数 をリセット( 左 右 両 方 に 共 通 に 含 ま れる by 変 数 値 のみ 抽 出 され 個 々の by 変 数 値 のオブザベーション 数 は 左 右 いずれか 短 い 方 に 合 わせて 出 力 されます) data m7; merge7 A=0;B=0; Obs name value1 value2 merge A(in=A) B(in=B); 1 A 11 111 by name; 2 B 21 221 if A=1 and B=1; ( 内 部 結 合 した 後 同 じ name 値 の 中 の 両 方 のデータでの 最 初 の Row のみ 抽 出 する 処 理 を 意 味 します) proc sql; reset print number; create table A1 as select *, monotonic() as s1 from A; 126
create table B1 as select *, monotonic() as s2 from B; select *, monotonic() as t from (select *, monotonic() as s from (select coalesce(a1.name, B1.name) as name, value1, value2, s1, s2 from A1 inner join B1 on A1.name = B1.name) group by s2 having min(s)=s) group by s1 having min(t)=s; quit; Row name value1 value2 s1 s2 s t 1 A 11 111 1 1 1 1 2 B 21 221 2 3 3 3 注 意 : 上 記 SQL は 1 対 n のマージ(by 変 数 (name)の 個 々の 値 がデータセット A ではすべて1つずつしか 存 在 せず データセット B では 複 数 存 在 する 可 能 性 がある 場 合 のマージ)の 場 合 に DATA ステップの 結 果 と 一 致 する SQL を 例 として 示 しています 以 下 の 例 のように n 対 mのマージ( 個 々の by 変 数 値 が 両 方 のデータセットに 複 数 存 在 する 可 能 性 があ る 場 合 のマージ)の 場 合 には 例 示 した SQL の 結 果 は DATA ステップの 結 果 と 異 なることに 注 意 して 下 さい ( 例 示 データ) n 対 m のマージ 例 になっていることに 注 意 A B obs name value1 obs name value2 1 A 11 1 A 111 2 B 21 2 A 112 3 B 22 3 B 221 4 C 31 4 B 222 5 B 223 6 D 441 7 D 442 基 本 的 な merge ステートメント+ by 変 数 の 指 定 (いずれかのデータセットに 含 まれる by 変 数 値 がすべ て 抽 出 され 個 々の by 変 数 値 のオブザベーション 数 は 左 右 いずれか 多 い 方 に 合 わせて 出 力 されます) data merge1; merge1 merge A B; Obs name value1 value2 by name; 1 A 11 111 2 A 11 112 3 B 21 221 4 B 22 222 5 B 22 223 6 C 31. 7 D. 441 8 D. 442 127
(1 対 n で 表 示 した 同 じ SQL)( SQL 結 果 は name 値 に 関 して 2*3=6 行 の Row を 出 力 します ) proc sql; reset print number; select coalesce(a.name, B.name) as name, value1, value2 from A full join B on A.name = B.name; quit; Row name value1 value2 1 A 11 111 2 A 11 112 3 B 22 221 4 B 22 223 5 B 22 222 6 B 21 221 7 B 21 223 8 B 21 222 9 C 31. 10 D. 442 11 D. 441 (1)のマージは 以 下 の DATA ステップのマージ 結 果 と 同 じです (8) merge ステートメント+ by 変 数 の 指 定 + 両 方 の in 変 数 を OR 条 件 で 結 合 して 指 定 data merge8; merge8 A=0;B=0; /* 記 述 しなくてもかまわない */ Obs name value1 value2 merge A(in=A) B(in=B); 1 A 11 111 by name; 2 A 11 112 if A=1 or B=1; 3 B 21 221 4 B 21 222 5 B 21 223 6 C 31. 7 D. 441 8 D. 442 128
お 問 合 せ 先 本 資 料 は 3 日 間 の Base SAS オンサイト 講 習 会 用 資 料 として 作 成 したものです 本 資 料 に 関 するご 質 問 その 他 講 習 実 施 等 に 関 するお 問 合 せは 以 下 の 宛 先 までお 願 いします データマインテック 株 式 会 社 本 社 201-0004 東 京 都 狛 江 市 岩 戸 北 3-3-6-405 info@dataminetech.co.jp なお 本 資 料 は 予 告 なく 改 訂 される 場 合 があります 下 記 のホームページで 公 開 する 最 新 の 資 料 をご 参 照 ください http://www.dataminetech.co.jp/ Copyright 2012 Data Mine Tech Ltd. 商 用 での 無 断 複 製 無 断 転 載 を 禁 じます 129