投稿

2015の投稿を表示しています

proc sql feedback - select句 * を展開したり、SASビューの定義をログに表示する - SAS

proc sql の feedback オプションについてのご紹介です。 テストコード 1 - proc sql feedback options msglevel=i ; /* テストデータ */ data TEST ; STR = "TEST" ; do I=1 to 1E5 ; R = ranuni(1) ; G = mod(I, 10) ; output ; end ; run ; %let TABLE_NAME = TEST ; proc sql feedback ; create table TEST1 as select * from &TABLE_NAME. /* コメント */ ; quit ; NOTE: Statement transforms to: の後に、SELECT句の * が展開された形で、SELECT文がログに表示されます。マクロ変数も展開され、コメントは削除されます。 71 proc sql feedback ; 72 create table TEST1 as 73 select * 74 from &TABLE_NAME. /* コメント */ 75 ; NOTE: Statement transforms to: select TEST.STR, TEST.I, TEST.R, TEST.G from WORK.TEST; NOTE: テーブルWORK.TEST1(行数100000、列数4)が作成されました。 76 quit ; NOTE: PROCEDURE SQL処理(合計処理時間): 処理時間 0.03 秒 CPU時間 0.04 秒 テストコード 2 - proc sql feedback : SQLビューを表示できます。 /* テストデータ2 */ data IDX ; G = 1 ; NOTE = "

proc sql ; describe ステートメント - データセットの定義内容をログに出力する - SAS

イメージ
proc sql で使用する describe ステートメントは、データセットの定義内容をログに表示するステートメントです。proc contents のログに表示するバージョンみたいな感じです。 1. describe table テストコード - create table create table で作成したデータセットに対して、describe ステートメントを使ってみます。 options msglevel=i ; proc sql noprint ; create table TEST1 ( A decimal ,B char(30) ,C varchar(10) ,D numeric ,E float ) ; describe table TEST1 ; quit ; 59 proc sql noprint ; 60 create table TEST1 61 ( 62 A decimal 63 ,B char(30) 64 ,C varchar(10) 65 ,D numeric 66 ,E float 67 ) 68 ; NOTE: テーブルWORK.TEST1(行数0、列数5)が作成されました。 69 describe table TEST1 ; NOTE: SQLテーブルWORK.TEST1は次のように作成されました: create table WORK.TEST1( bufsize=65536 ) ( A num, B char(30), C char(10), D num, E num ); 70 quit ; NOTE: PROCEDURE SQL処理(合計処理時間): 処理時間 0.02 秒 CPU時間 0.03 秒 文字項目はすべて c

動かして覚えるマクロ変数の展開 - && など &が複数あるパターン - SAS

マクロ変数の値を用いるには、& を使用します。この & を複数使用することで、マクロ変数を展開して、展開した値のマクロ変数を展開し、さらにその値のマクロ変数を・・・というような使い方ができます。 テストコード 1 - & が 1~3個 %let HELLO = SAS ; %let SAS = WORLD ; %put HELLO = &HELLO. ; %put HELLO = &&HELLO. ; %put HELLO = &&&HELLO. ; 59 %let HELLO = SAS ; 60 %let SAS = WORLD ; 61 62 %put HELLO = &HELLO. ; HELLO = SAS 63 %put HELLO = &&HELLO. ; HELLO = SAS 64 %put HELLO = &&&HELLO. ; HELLO = WORLD テストコード 2 - & いっぱい %let NUM = 1 ; %let CLASS_1 = FIRST ; %let FIRST = LAST ; %put CLASS = &CLASS._&NUM ; /* WARNING */ %put CLASS = &CLASS_&NUM ; /* WARNING */ %put CLASS = &&CLASS_&NUM ; %put CLASS = &&&CLASS_&NUM ; %put CLASS = &&&&CLASS_&NUM ; %put CLASS = &&&&&CLASS_&NUM ; %put CLASS = &&&&&&CLASS_&NUM ; 67 %let NUM

UTF-8 環境で、Shift-JIS の固定長ファイルを読み込むのって大変という話 - SAS

イメージ
前回の記事、「 Shift-JIS の固定長ファイルを UTF-8 環境に読み込む (kcvt関数) - SAS 」の余談。 「 Shift-JIS の固定長ファイルを UTF-8 環境に読み込む (kcvt関数) - SAS 」 にて、kcvt 関数を用いて、ファイルを読み込んでみました。 テスト用に用いたファイルでは、文字コード変換が必要な項目は1項目だけだったので、まだ良かったのですが、もし変換しなければならない項目が10項目、20項目、、、とあると、その項目の数だけ、length ステートメントと kcvt 関数を書かなければなりません。 これはとても面倒くさいです。 filename ステートメント、または infile ステートメントにて使用できる encoding= オプションを用いれば読め...ません。 このオプションは、CSV ファイルや TSV ファイルのように、区切り文字(セパレータ)があれば使えますが、固定長ファイルでは理想通りには使うことができません。 前回の記事のテストコードを流用して、固定長ファイルの読み込み時に encoding= を使うと、どうなるのか試しに使ってみます。 テストコード - encoding=sjis を追加 filename IN "/folders/myfolders/test.txt" ; data TEST ; infile IN recfm=F lrecl=28 encoding=sjis ; input @001 CUSTOMER_ID 5. @006 NAME $20. @026 AGE 2. ; run ; 実行ログ 56 filename IN "/folders/myfolders/test.txt" ; 57 58 data TEST ; 59 infile IN recfm=F lrecl=28 encoding=sjis ; 60 input @001 CUSTOMER_ID 5. 61

Shift-JIS の固定長ファイルを UTF-8 環境に読み込む (kcvt関数) - SAS

イメージ
読み込む固定長ファイル(Shift-JIS) 1~ 5バイト:顧客ID 6~25バイト:顧客名 26~27バイト:年齢 28バイト:改行コード(LF) 00001さとう たろう 27 00002こばやし さなえ 54 00003みたらい しょう 22 00004やぶき かける 24 00005はやし けんた 21 テストコード filename IN "/folders/myfolders/test.txt" ; data TEST ; infile IN recfm=F lrecl=28 ; input @001 CUSTOMER_ID 5. @006 NAME $20. @026 AGE 2. ; run ; Shift-JIS 環境に読み込むときは、上記のような感じでいいのですが、UTF-8 環境に読み込ませるときちんと読み込めません。 テストコード (修正) data TEST ; infile IN recfm=F lrecl=28 ; length NAME $30. ; input @001 CUSTOMER_ID 5. @006 NAME $20. @026 AGE 2. ; NAME = kcvt(NAME, 'sjis', 'utf8') ; run ; kcvt関数で、Shift-JIS の値を UTF-8 に変換します。第1引数に変換する項目、第2引数に変換前の文字コード、第3引数に変換後の文字コードを記載します。 これで文字コードを変換することができますが、input ステートメントの前に、length ステートメントで項目の長さを長くしておく必要があります。Shift-JIS は1文字1~2バイトで表現されますが、UTF-8は1文字1~4バイトで表現されます(IVSを入れれば、7, 8バイトもありますが)。なので、長さをそのままにしておくと文字切れが発生してしま

Linuxコマンド: date で◯か月前 / ◯か月後を取得するときの注意

date コマンドは、日付を取得したり、整形して表示したり、◯日後や◯か月後、◯年前の日付を表示したりすることができます。 ◯か月前や◯か月後を使用する時が曲者で、月末に近い日に実行すると、思っていた動作をしてくれないことがあります。 $ date 2015年 9月 6日 日曜日 16:05:22 JST $ date -d "2015-08-31" 2015年 8月 31日 月曜日 00:00:00 JST $ date -d "2015-08-31 1 month" 2015年 10月 1日 木曜日 00:00:00 JST $ date -d "2015-01-31 1 month" 2015年 3月 3日 火曜日 00:00:00 JST 8月31日の1か月後が10月1日になったり、1月31日の1か月後が3月3日になったりします。月によって◯か月後の計算をきちんとしてくれるわけではないようです。 実施日の翌月末を取得するには、実施月の 1日に変換してから、2ヶ月後の1日前を指定することで取得できます。 $ date -d "`date '+%Y/%m/01' -d "\`date '+%Y/%m/01' \` 2 month"` 1 day ago" 2015年 10月 31日 土曜日 00:00:00 JST 指定した日付の翌月の月末を取得する場合は、以下のように書きます。 $ date -d "`date '+%Y/%m/01' -d "\`date '+%Y/%m/01' -d 2015/08/31\` 2 month"` 1 day ago" 2015年 8月 31日 月曜日 00:00:00 JST $ date -d "`date '+%Y/%m/01' -d "\`date '+%Y/%m/01' -d 2015/01/31\` 2 month"` 1 day ago" 2015年 2月 28日 土曜日 00:00:

数値を丸める関数 round, rounde, roundz の違い - SAS

イメージ
round 関数 四捨五入ぽい計算をしてくれる関数です。 第1引数がだいたい中間の値(近似値)の場合は、絶対値が大きい方に丸めます。 rounde 関数 偶数丸め(銀行丸め / JIS丸め)ぽい計算をしてくれる関数です。 第1引数がだいたい中間の値(近似値)の場合は、偶数の方に丸めます。 roundz 関数 偶数丸め(銀行丸め / JIS丸め)計算をしてくれる関数です。 round 関数や rounde 関数と違い、ちょうど中間の値で丸めてくれます。ただし、第2引数が1以下であったり、整数の逆数(例. 整数3 の逆数 1/3)でない場合だと、実際の計算と違う値になることがあります。 偶数丸めとはなにかというと、丸めをする桁数の1つ上の桁数が偶数の値に丸める処理のことです。 例えば、小数第1位を四捨五入する場合、0.5 は 1 になりますが、偶数丸めでは 0 になります。0.5 は、1 と 0 のちょうど中間で、偶数は 0 の方なので、偶数丸めでは 0 に丸められます。では、1.5 を小数第1位で四捨五入すると 2 になり、偶数丸めでも 2 になります。 ※ ゼロは奇数ではなく、偶数です 値によって丸められ方が変わる偶数丸めですが、何がメリットがあるかというと、丸めた値の合計などを求めるときにあります。値を丸めてしまうと実際の値とは異なった値になってしまうため、誤差が生じてしまいます。このとき、四捨五入よりも偶数丸めの方が誤差が少ないというメリットがあります。 ところで、言語によって round 関数で実装されている丸め方は違います。エクセルでは四捨五入ですが、VBAだと偶数丸めです。round 関数を使用する場合、使用している言語の仕様を調べておくとトラブルを回避できるかと思います。 さてさて、実際に SAS でのそれぞれの関数の違いを見てましょう。 (コード内に使用している proc report の指定行を強調する方法については、 proc report 指定行(◯行目)を強調する - SAS をご参考ください。) /* ORG で指定した数に対して、10回 数値ADDを加算していき、 */ /* 加算していくたびに、ROUNDで指定した桁で丸め処理を実施する

数値定数、SAS日付定数、SAS時間定数、SAS日時定数の表現方法

イメージ
数値定数、SAS日付定数、SAS時間定数、SAS日時定数の色々な書き方のご紹介です。 数値定数 title "数値定数" ; data TEST_NUM ; N = 1234 ; output ; N = -123 ; output ; N = +123 ; output ; N = 0010 ; output ; N = 0.123 ; output ; N = 1E10 ; output ; /* 指数表記 : 1 × 10の10乗 = 10000000000 */ N = 2.1E2 ; output ; /* 指数表記 : 2.1 × 10の 2乗 = 210 */ N = 1E-3 ; output ; /* 指数表記 : 2.1 × 10の-3乗 = 0.001 */ N = 2.5E-2 ; output ; /* 指数表記 : 2.5 × 10の-2乗 = 0.025 */ N = 0x ; output ; /* 16進数 : 10進数 0 */ N = 010x ; output ; /* 16進数 : 10進数 16 */ N = 0FFx ; output ; /* 16進数 : 10進数 255 */ N = 0FFFFx ; output ; /* 16進数 : 10進数 65535 */ N = . ; output ; /* 欠損値 */ N = .A ; output ; /* 特殊欠損値 A */ N = ._ ; output ; /* 特殊欠損値 _ */ run ; proc print data=TEST_NUM ; format N comma22.4 ; run ; SAS日付定数 title "SAS日付定数" ; data TEST_DATE ; DATE = '01JAN2015'd ; output ; /* 2015/01/01 */ DATE = '31AUG2015'd

proc report 指定行(◯行目)を強調する - SAS

イメージ
proc report で指定した行(◯行目)だけを強調表現する方法です。 /* テストデータ */ data TEST ; do I=1 to 10 ; R = ranuni(int(datetime())) ; output ; end ; run ; ods rtf file="/folders/myfolders/test.rtf" ; proc report data=TEST nowd ; column I R ; define I / display ; define R / display format=12.9 ; compute I ; COUNT + 1 ; /* 5行目だけに適用 */ if COUNT = 5 then do ; call define(_ROW_, 'style', 'style=[Color=red BackgroundColor=Yellow]') ; end ; endcomp ; run ; ods rtf close ; compute内にて、変数 COUNT を用いて、行番号をカウントしています。if COUNT = 5 then で 5行目だけに、call define が実行されるようにします。call define では 文字色を赤、背景色を黄色にするように設定しています。 RTF の出力結果を確認すると、5行目だけちゃんと強調されています。 せっかくなので、もっと強調してみる style=[~] と、四角括弧の中に設定するスタイルを記載します。文字色、背景色の設定だけでなく、文字のスタイル、フォント、罫線のスタイルや色なども設定できます。 強調したい行をより強調表現してみましょう。 ods rtf file="/folders/myfolders/test.rtf" ; proc report data=TEST nowd style(header)=[Fontfamily='Couriel' FontWeight=bold FontSize=3 Backgrou

NOTE: MERGEステートメントにBY値を繰り返すデータセットが複数あります。~SASログ入門 #3~

イメージ
データセットとデータセットの結合に使う みんな大好き mergeステートメントですが、n対n (多対多)の結合を行うことができません。正確には、n対n の結合をしようとすると、結合はできるのですが、SQLでの n対n の結合のように結合してくれません。 そんな、mergeステートメントで、n対n の結合をしてしまったとき、出てくるNOTEメッセージ「NOTE: MERGEステートメントにBY値を繰り返すデータセットが複数あります。」のご紹介です。 下記は、n対1 の結合をしようとして、間違えて n対n の結合をしてしまったサンプルコードです。 /* 顧客データ */ data CLIENT_MASTER ; infile cards dlm="," ; input LATEST_FLG CHANGED_DATE : date8. CLIENT_NO CLIENT_NAME : $20. BIRTH_DATE : date8. EMAIL_ADDRESS : $100. ; format CHANGED_DATE yymmddn8. BIRTH_DATE yymmddn8. ; cards ; 1,10DEC2015,001,JOHN,01JAN1980,TEST@TEST.com 0,12JUL2010,001,JOHN,01SEP1980,TEST@TEST.com 1,10DEC2015,002,Emily,01JAN1980,TESUTO@test.com 0,10DEC2015,002,Emily,01JAN1980, 0,10DEC2015,002,Emily,01JAN1981, 1,10DEC2014,003,Ann,12OCT1990,test@test.co.jp run ; /* 取引データ */ data TRANSACTION_PROCESS ; infile cards dlm="," ; input PROCESS_DT : datetime18. CLIENT_NO PRODUC

環境によっては ls, ps の値を変えてしまうオプションがある・・・らしいので注意 - SAS

SAS 雲丹では変わらなかったのですが、下記のオプションを変更すると、ls, ps の値が変わってしまうようです。環境によっては起きないみたいです。 PAPERSIZE ORIENTATION TOPMARGIN BOTTOMMARGIN LEFTMARGIN RIGHTMARGIN 日本語オンラインヘルプには下記のように記載があります。 このオプションの値を変更すると、移植可能な LINESIZE=および PAGESIZE=システムオプションの値が変更される場合があります。 SAS 9.4 システムオプション:リファレンス 第3版(PDF) 自分の使っている環境が、これらのオプションを使用したとき、または proc optload を使用したとき、ps, ls の値が変わる環境なのかどうか、気をつけてみてください。 変わってしまう環境の場合は、ps, ls のオプションを再設定するように心掛けたり、上記のオプションたちを使わないようにするといったことが必要かもしれません。 参考サイト ODS出力時の用紙サイズや余白などを設定するオプション [まとめ] | SAS忘備録

NOTE: 以下の箇所で◯◯を◯◯に変換しました。~SASログ入門 #2~

今回の注目ログメッセージは、 NOTE: 以下の箇所で数値を文字値に変換しました。 NOTE: 以下の箇所で文字値を数値に変換しました。 の、2つです。 「NOTE: 以下の箇所で数値を文字値に変換しました。」 data TEST ; length STR $5. ; /* 変数STRは文字です */ STR = 1234 ; putlog STR= ; run ; 上記のdataステップでは、変数STRをlengthステートメントで文字として定義しています。その文字変数STRに対して、数値1234 を格納しようとしています。 60 data TEST ; 61 length STR $5. ; /* 変数STRは文字です */ 62 STR = 1234 ; 63 putlog STR= ; 64 run ; NOTE: 以下の箇所で数値を文字値に変換しました。 (行:カラム) 62:9 STR=1234 NOTE: データセットWORK.TESTは1オブザベーション、1変数です。 NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.02 秒 CPU時間 0.02 秒 文字変数に対して、数値は格納できないので、1234という数値は文字に変換されて、変数STRに格納されます。このとき、ログに、「NOTE: 以下の箇所で数値を文字値に変換しました。」が出力されます。このメッセージは、文字が入るべき箇所で数値が来ると出力されるログメッセージです。 代入式だけでなく関数の引数でも発生します。substr関数の第1引数は文字であるべきですが、下記のコードでは数値が記載されています。 63 data _null_ ; 64 STR = substr(123, 1, 1) ; 65 run ; NOTE: 以下の箇所で数値を文字値に変換しました。 (行:カラム) 64:16 NOTE

文字項目の長さが決定するタイミング - SAS

イメージ
lengthステートメントを使用しない場合、文字の長さが決定するタイミングは、dataステップの中で該当変数が初めて登場してくるところです。 data TEST ; A = "12345" ; output ; A = "01234567890" ; output ; run ; proc contents data=TEST ; run ; 上記のプログラムでは、変数 A に最初の式で5バイトの文字列を格納し、次の式で10バイトの文字列を格納しようとしています。文字の長さは、最初の式で決定するので、変数 A の長さは5バイトです。なので、次の式で10バイトの文字列をすべて格納することはできません。 初めて登場するタイミングで決定すると言いましたが、この「初めて」というのは実行されない式にも当てはまります。 data TEST ; A = 1 ; if A = 0 then B = "1" ; B = "12345" ; run ; proc contents data=TEST ; run ; if 文の中の B = "1" ; は実行されませんが、dataステップの中で「初めて」変数 B が登場するタイミングです。しっくりこないかもしれませんが、ここが変数 B の長さが決定するタイミングで、長さは1バイトとなります。変数の長さは1バイトなので、最後の5バイトの文字列をすべて格納することはできません。 場合によってはバグの元にもなるかもしれないので、事前にlengthステートメントで、文字の長さを決めておくのが良いかと思います。 バグ発生経験者より自戒を込めて 参考サイト SAS Base Programmer 練習問題23 | study SAS

動かして覚える file ステートメント dropover , stopover オプション

イメージ
data ステップの file ステートメントには、出力ファイル1行あたりの最大バイト数を指定する lrecl= オプションがついています。デフォルトでは、この lrecl= オプションを超えた値を出力しようとすると、次の行に超えた分の値が書き込まれます。 data TEST ; length A $10. ; A = "1" ; output ; A = "1234567890" ; output ; A = "ABCDEFG" ; output ; run ; filename OUT "/folders/myfolders/test.txt" ; data _null_ ; set TEST ; file OUT lrecl=9 ; put A ; run ; dropover オプション lrecl= の値を超えたとき、該当の行を削除したい場合は、fileステートメントに dropover オプションを付けます。 68 data _null_ ; 69 set TEST ; 70 file OUT lrecl=9 dropover ; 71 put A ; 72 run ; NOTE: 出力ファイルOUT : ファイル名=/folders/myfolders/test.txt, 所有者名=root,グループ名=vboxsf, アクセス権限=-rwxrwx---, 更新日時=2015年07月22日 21時01分14秒 NOTE: 3レコードを出力ファイルOUTに書き込みました。 最小レコード長は0です。 最大レコード長は7です。 NOTE: DROPOVERオプションを指定しているため、出力の一部を無視しました。 NOTE: データセットWORK.TESTから3オブザベーションを読み込みました。 NOTE: DATAステートメント処理(合計処理時間): 処理時間

ソート処理の処理時間を早く、メモリ消費を抑えたい - sort プロシジャ noequals オプション (非安定ソート) - SAS

mergeステートメントの前処理としてお馴染みの sort プロシジャについて、noequals オプションのご紹介です。 noequals オプションを付けることで、非安定ソートを行うことができます。デフォルトの設定では equals で、安定ソートが設定されています。noequals の最大のメリットは、デフォルトの equals と比べて、 CPU時間が短く、メモリが少なくすむことです! さて、そもそも、安定ソートとはなんでしょう。安定ソートとは、Wikipedia先生から引用しますと、 安定ソート(あんていソート、stable sort)とは、ソート(並び替え)のアルゴリズムのうち、同等なデータのソート前の順序が、ソート後も保存されるものをいう。つまり、ソート途中の各状態において、常に順位の位置関係を保っていることをいう。 たとえば、学生番号順に整列済みの学生データを、テストの点数順で安定ソートを用いて並べ替えたとき、ソート後のデータにおいて、同じ点数の学生は学生番号順で並ぶようになっている。 安定ソート | Wikipedia という感じです。ソートする前の並び順が維持されるのが安定ソート。ソートする前の並び順が無視されるのが非安定ソートです。 Wikipedia の例を元にサンプルデータを作ってみます。データは学籍番号順に並んでいます。 学籍番号 点数 001 80 002 90 003 80 004 100 005 90 006 80 上記のサンプルデータを点数で安定ソートしてみます。学籍番号の順番は維持されています。 学籍番号 点数 001 80 003 80 006 80 002 90 005 90 004 100 非安定ソートしてみると、点数の順に並んでいますが、安定ソートと並び順が異なります。(例のために並び順が異なるようにしていますが、一致することもあります。) 学籍番号 点数 001 80 006 80 003 80 005 90 002 90 004 100 proc sort noequals テストコード SASプログ

NOTE: 変数◯は初期化されていません。~SASログ入門 #1~

イメージ
SASのログの中には、バグになるかもしれない / バグかもしれないメッセージが、ERROR や WARNING ではなく、通常メッセージの NOTE で出力することがあります。そのメッセージを見逃してしまうと、後々、バグになる・・・かもしれません。 では、チェックすべき NOTE: メッセージとはどんなものなのか。 「きっと役立つ、バグになりそうなNOTE:のチェック | SAS Utility」 にて、そういったNOTE: メッセージの一覧がご紹介されています。これらのメッセージについて、ひとつずつ、メッセージを出力させるためのSASプログラムと簡単な解説を添えてご紹介していきたいと思います。 今回、ご紹介しますのは、「 NOTE: 変数◯は初期化されていません。 」です。 59 data TEST ; 60 A = B ; 61 run ; NOTE: 変数Bは初期化されていません。 NOTE: データセットWORK.TESTは1オブザベーション、2変数です。 NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 変数として、まだ作成されていない B を変数 A に代入しようとしているため、該当のメッセージが出力されています。このとき、dataステップの実行は止まらず、後続の処理が実行され、データセット TEST は作られてしまいます。変数 A, B には欠損値が格納されて出力されます。 上記の動作はデフォルトでの動作で、初期化されていない変数があったときの動作は、オプションで設定することができます。そのオプションが、varinitchk オプションです。nonote, note(デフォルト), warning, error の4種類が設定できます。 varinitchk 設定値 ログメッセージ dataステップ nonote なし 続行 note (デフォルト) NOTE: 続行 warning (省略: war

missingオプション - 数値欠損値の出力結果を . ドットから変更する - SAS

イメージ
数値の欠損値は、デフォルトで、. で出力されますが、別の文字にしたいときは、missingオプションを使うと、別の文字に変更することができます。値は、1文字だけ設定することができます。 options missing="M" ; data TEST ; length B $10. C $10. ; A = 1 ; B = "ABCDEFG" ; C = "123456" ; output ; A = 2 ; B = "09"x || "BBB" ; C = "1,2,3" ; output ; A = 3 ; B = "B," || "09"x || ",B" ; C = "" ; output ; A = . ; B = "" ; C = "" ; output ; run ; filename OUT "/folders/myfolders/test.txt" ; data _NULL_ ; set TEST ; file OUT dlm="09"x dsd ; put A ~ B ~ C ~ ; run ; これで、数値の欠損値の出力を変更することができました。しかし、特殊欠損値の場合は、変更されませんのでご注意ください。 options missing=" " ; data TEST1 ; A = . ; B = "" ; C = .M ; D = .A ; run ; filename OUT "/folders/myfolders/test1.txt" ; data _NULL_ ; set TEST1 ; file OUT dlm="09"x dsd ; put A ~ B ~ C ~ D ~ ; run ; 参考サイト

動かして覚える file ステートメント dsd オプション / ~ チルダ修飾子 ~値にダブルクォーテーションを付ける~ - SAS

イメージ
SASデータセットの内容を CSVファイルに書き出して、エクセルに読み込ませたい、というとき、値の中にカンマがあるとエクセルにうまく読み込んでくれません。どんな感じで読み込まれてしまうのか。試しに、DATAステップの file ステートメントと put ステートメントで、CSV ファイルを作ってみましょう。 ファイルの出力 - カンマ区切り data TEST ; length B $10. C $10. ; A = 1 ; B = "ABCDEFG" ; C = "123456" ; output ; A = 2 ; B = "09"x || "BBB" ; C = "1,2,3" ; output ; A = 3 ; B = "B," || "09"x || ",B" ; C = "" ; output ; A = . ; B = "" ; C = "" ; output ; run ; filename OUT "/folders/myfolders/test.txt" ; data _NULL_ ; set TEST ; file OUT dlm="," ; put A B C ; run ; ※ "09"x = タブ 作成した CSV ファイルをエクセルにカンマ区切りで読み込ませてみると、値がずれて読み込まれてしまいます。 ファイルの出力 - カンマ区切り dsd オプション付き カンマを値として読み込ませるには、ダブルクォーテーション " で囲む必要があります。ダブルクォーテーションを付けるために、file ステートメントに dsd オプションを付けます。dsd オプションは値にカンマがある場合、ダブルクォーテーションを付けてくれます。 data _NULL_ ; set TEST ; file OUT dlm=&

動かして覚える infileステートメント filevar オプション ~複数ファイルをヘッダを飛ばして一括で読み込む~ - SAS

イメージ
複数のファイルを dataステップ1回で読み込もうとしたとき、それぞれのファイルに読み込ませたくないヘッダーがあると、firstobs オプションを使ってもヘッダを飛ばせず上手く読み込まれません。しかし、filevar オプションを使ってみたところ、上手く全てのヘッダを飛ばして読み込ませることができたので、その方法と filevar オプションについてご紹介します。 (※ filevar オプションではなく、eov オプションを用いた解決方法が、データステップ100万回 SAS新手一生 の記事「 filenameで複数ファイルを一括指定して、読み込む場合に各ファイル1行目がラベル行だと、難しいことになるがeovをうまく使えば解決できる話 」にて、ご紹介されていますので、こちらもご参考ください。) (※ filevar オプションによる解決方法は、コーディングミスによる無限ループの危険性があるから、ヘッダを飛ばすだけなら、eov オプションの方が良いかもしれません。) サンプルに用意した入力ファイルは、以下のようなファイルです。 格納場所  : /folders/myfolders/filevar/ 文字コード : Shift-JIS 改行コード : CRLF 区切り文字 : , (カンマ) なにも考えずに読み込むと、以下みたいに、ヘッダが残ってしまいます。 filename IN "/folders/myfolders/filevar/test?.txt" ; data TEST ; infile IN dlm=',' dsd missover lrecl=1048576 encoding="sjis" termstr=CRLF ; input V1 : $CHAR10. V2 : 8. V3 : $CHAR60. ; run ; filename のファイル名に指定している ? は1文字にマッチするワイルドカードです。 encoding オプション 入力ファイルの文字コードを指定する。 termstr オプション 入力ファイルの改行コードを指定する。 inf

whereステートメントで処理時間を遅くする書き方 ~年月でオブザベーションを絞り込む~ - SAS

年月でオブザベーションを絞り込む方法について質問を受けたとき、処理効率の話になったので、その話をまとめてみました。 オブザベーションを条件式で絞り込む方法には、whereステートメントとサブセット化 ifステートメントがあります。基本的には、whereを使ったほうが処理速度が早いのですが、書き方によっては if 並に遅くなってしまいます。 下記に、2015年6月のデータのみに絞り込むための 5つのサンプルパターンを作成しました。 年月で絞り込むテストコード options lognumberformat ; /* ログのオブザベーション数にカンマを付ける */ /* テストデータ */ data TEST ; format DT yymmdds10. ; do I=1 to 100000000 ; /* 1億 */ /* 2015/01/01 から 365日間のいずれかのSAS日付を項目 DT に格納します */ DT = mdy(01, 01, 2015) + int(365 * ranuni(1)) ; output ; end ; run ; /* 2015年6月に絞り込むためのマクロ変数を定義します */ %let TARGET_MONTH = %sysfunc(mdy(6, 1, 2015)) ; %let TARGET_YYYY = %sysfunc(year(&TARGET_MONTH.)) ; %let TARGET_MM = %sysfunc(month(&TARGET_MONTH.)) ; %put &=TARGET_MONTH. ; %put &=TARGET_YYYY. ; %put &=TARGET_MM. ; /* intnx関数から来月の月初を算出して、絞り込む */ data TEST1 ; set TEST ; where &TARGET_MONTH. <= DT < intnx('MONTH', &TARGET_MONTH., 1, 'BEGINNING') ; run ; /* intnx関数から今月の月末を算出して、絞り込む */ data

プログラムの処理時間を計測したい - SAS

イメージ
SASプログラムの処理時間は、1つのdataステップやプロシージャ単位でログに表示されるのだけど、複数ステップの合計処理時間を取得したい、プログラム全体の処理時間を知りたいとかあるかと思います。処理時間を計測するためには、現在の日時を取得する datetime関数を用いることで計測することができます。 処理時間を計測するテストコード /* 処理時間を計測したい処理直前の日時をマクロ変数 START_TIME に格納 */ data _null_ ; call symputx('START_TIME', datetime()) ; run ; /* 処理を計測したいサンプルコード */ data TEST1 ; do I=1 to 10000000 ; R = ranuni(1) ; output ; end ; run ; /* 処理直後の日時 - 処理直前の日時 = 処理時間 */ data _null_ ; PROCESS_TIME = datetime() - &START_TIME. ; putlog PROCESS_TIME= ; run ; 処理時間を計測した実行ログ 59 data _null_ ; 60 call symputx('START_TIME', datetime()) ; 61 run ; NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 62 63 data TEST1 ; 64 do I=1 to 10000000 ; 65 R = ranuni(1) ; 66 output ; 67 end ; 68 run ; NOTE: データセットWORK.TEST1は10,000,000オブザベーション、2変数です。 NOTE: DATAステートメント処理(合計処理時間):

SAS雲丹 (SAS University Edition) におけるオートコンプリート機能(コード補完機能)の出し方 Ctrl+Space

イメージ
※ 下記の結果は、SAS雲丹 - SAS studio 3.3 にて実行しています。 SAS雲丹(SAS University Edition) のエディタには、オートコンプリート機能があります。オートコンプリート機能とは、ユーザが次に入力するキーワードを予測して表示させる機能で、なかなか便利です。 例えば、「da」と入力すると、もしかして data?みたいにキーワード一覧を表示してくれます。右側に表示されているのは構文ヘルプで、選択したステートメントなどの情報が記載されているものです。 このオートコンプリート機能ですが、入力途中にしか表示されないかと思っていたのですが、ショートカットキーで表示することができました。ショートカットキーは、ctrl+Spaceです。 例えば、単に「p」と1文字だけ入力したときは、オートコンプリートは出てきません。カーソルを移動させず、この状態で ctrl+Spaceを押すと下記のように表示されます。 このオートコンプリート機能ですが、なにも入力されていないところで実行すると、マクロステートメントまたはグローバルステートメントの一覧が表示されます。どちらが表示されるかは、カーソル位置によって異なるようですが、、カーソル位置の直後にマクロがあるかできまってるぽい?です。 コメント欄にて、ctrl+Spaceを押すと、色, 出力形式, 入力形式, マクロ関数, SAS関数, 統計量キーワード, スタイル要素, スタイル属性を表示することができます。これらは、ctrl+Spaceを押すことで切り替えることができ、ctrl+shift+Spaceで逆順に切り替えることができます。 (なんでコメントでこれらのオートコンプリートが出てくるのだろう...) また、コメントだけでなく、int関数, ranuni関数、mdy関数などの関数内の丸括弧の中でも、ctrl+Spaceを押すと上記が表示されます。(なんで関数内で出るのだろうか...)