2015年12月24日木曜日

SASでクリスマスツリーを描いてみる



SGPLOTプロシジャで遊んでみました。

HTML出力が有効になっている前提です。
バージョンや環境によってうまく表示されないかも。。


*** ツリー描画用データ作成 ;
data TREE;
input X Y1-Y5;
cards;
0 1 0 -1 -2 -4
;
run;

*** ツリー描画 ;
title ;
proc sgplot data=TREE noautolegend;
   scatter x=X y=Y1 /  markerattrs=(symbol=starfilled size=0.8cm color=yellow);
   scatter x=X y=Y2 /  markerattrs=(symbol=trianglefilled size=1cm color=green);
   scatter x=X y=Y3 /  markerattrs=(symbol=trianglefilled size=2cm color=green);
   scatter x=X y=Y4 /  markerattrs=(symbol=trianglefilled size=3cm color=green);
   scatter x=X y=Y5 /  markerattrs=(symbol=squarefilled size=0.6cm color=brown);
   inset "Happy Holidays !!"/ position=bottom textattrs=(size=50cm);
   xaxis min=-3 max=3  display=none;
   yaxis min=-5 max=1  display=none;
run;




雪も降らせてみました。(SAS9.4以上で動作します)

*** ツリー描画用データ作成 ;
data TREE;
input X Y1-Y5;
cards;
0 1 0 -1 -2 -4
;
run;

*** ゆき描画用データ作成 ;
data SNOW;
  call streaminit(123);
  do X=-3 to 3 by 0.2;
     SNOW = rand('uniform')*8-4;
     output;
  end;
run;

data DT1;
  set TREE SNOW;
run;

*** ツリーとゆき描画 ;
title ;
proc sgplot data=DT1 noautolegend;
   styleattrs wallcolor=black;
   scatter x=X y=Y1 /  markerattrs=(symbol=starfilled size=0.8cm color=yellow);
   scatter x=X y=Y2 /  markerattrs=(symbol=trianglefilled size=1cm color=green);
   scatter x=X y=Y3 /  markerattrs=(symbol=trianglefilled size=2cm color=green);
   scatter x=X y=Y4 /  markerattrs=(symbol=trianglefilled size=3cm color=green);
   scatter x=X y=Y5 /  markerattrs=(symbol=squarefilled size=0.6cm color=brown);
   scatter x=X y=SNOW / markerattrs=(symbol=circlefilled size=0.1cm color=white);
   inset "Happy Holidays !!"/ position=bottom textattrs=(color=white size=50cm);
   xaxis min=-3 max=3  display=none;
   yaxis min=-5 max=1  display=none;
run;


単純な仕組みですが、散布図のシンボルを★▲■●にしてサイズを大きくして表示させています。


2015年12月18日金曜日

TITLEステートメントで左寄せしたり書式を設定したりする。



(※書式設定はHTMLやRTF等の一部出力のみ対応しています)


まず普通に出力した場合、タイトルは中央寄せになります。

title "あいうえお" ;
proc print data=SASHELP.CLASS (obs=5);
run;






① NOCENTERオプション


NOCENTERオプションを設定すると、タイトルやプロシジャの結果などすべて左寄せになります。
(ちなみにSAS Studioだと何故か設定できなかったり、できたり挙動がおかしい。。)

options nocenter;

title "あいうえお" ;
proc print data=SASHELP.CLASS (obs=5);
run;

options center;



CENTERオプションで中央寄せ(デフォルト)に戻せます。




② TITLEステートメントのオプション


TITLEステートメントには書式を設定するオプションがあります。


構文
 TITLE  書式  "タイトル" ;



書式には以下が設定できます。

書式設定内容
COLOR=色文字色
BCOLOR=色文字の背景色
FONT="フォント"フォント
HEIGHT=サイズフォントサイズ
BOLD太字で表示
ITALICイタリックで表示
JUSTIFY= LEFT | CENTER | RIGHT文字の位置
LINK = 'URLを指定'ハイパーリンクの設定
UNDERLINE = 1 ~ 3下線
SAS/GRAPHでは数字によって下線の太さが変わり、HTML等のODS出力ではどの数字でも太さは変わらないようです。



いくつか例を見ていきましょう。


  • タイトルだけ左寄せにする。
title justify=left "あいうえお" ;
proc print data=SASHELP.CLASS (obs=5);
run;




  • 文字ごとに右寄せしたり左寄せしたりする。
title justify=left "あい" justify=center "うえ"  justify=right "お";
proc print data=SASHELP.CLASS (obs=5);
run;




  • その他フォント等も設定できる。
title color="red"  font="MS P明朝"  height=20pt  "あいうえお" ;
proc print data=SASHELP.CLASS (obs=5);
run;




FOOTNOTEでも同様の設定が行えます。


2015年12月15日火曜日

【意外に使えるCATT関数】各文字の末尾の半角スペースを削除して連結する



構文


   CATT( 文字1 , 文字2 , ・・・)


各文字の末尾の半角スペースを削除して連結します。



簡単な例

data DT1;
    length VAR1 $10.;
    VAR1 = catt( 'aa' , '  -  ' , 'bb' );
run;

 VAR1  
 aa  -bb 



CATT関数が役に立つ例

data DT2;
    A = "aaa";
    B = "bbb";
run;
 aaa 
 bbb 

上のデータから、以下のように加工した変数VAR1を作成したいとします。

 A  
 B  
VAR1  
 aaa 
 bbb 
 aaa (bbb) 

(カッコの前に半角スペースを入れて連結したい)


*** 導出例 ;
data DT3;
    set DT2;    
    length VAR1 $20.;
    VAR1 = catt( A, ' (', B, ')' );
run;

こういう場合はCATT関数が一番スッキリとしたプログラムになると思います。



あわせて読むと役立つ記事

PUT関数の小技
半角スペースを取り除いてくれる関数達



2015年12月7日月曜日

REPORTプロシジャ入門6:要約行の追加【BREAK, RBREAK】



BREAK・RBREAKを使って、合計や平均などの要約行を追加する事ができます。

まずは構文から。




  要約行を追加  【RBREAKステートメント】


※ 黄色部分が要約行





















ざっくり解説

  RBREAK  BEFORE   /  SUMMARIZE ;

先頭に要約行を追加します。
「RBREAK  AFTER」 だと末尾に追加されます。


  DEFINE  変数2  /  ANALYSIS  統計量 ;

要約値の計算は、ANALYSISオプション等の「要約統計量の出力」が設定されたものに対して行われます。

📝
ANALYSISオプションは予期せぬ結果になりやすいので以下記事も要確認。
REPORTプロシジャ入門10:数値変数の落とし穴




 グループ毎に要約行を追加  【BREAKステートメント】























ざっくり解説

  DEFINE  変数1 / ORDER ;

まず変数1のグループ毎に要約行を追加するため、ORDERオプションで並び替えておく。

📝
ORDERオプションは欠損値のオブザベーションが除外されたり、並び順がおかしくなる注意点もあるので以下記事も要参照。
  BREAK  BEFORE  変数1  /  SUMMARIZE ;

変数1のグループ先頭に要約行を追加します。
「BREAK  AFTER  変数1」 だとグループ末尾に追加されます。


  DEFINE  変数2  /  ANALYSIS  統計量 ;

要約値の計算は、ANALYSISオプション等の「要約統計量の出力」が設定されたものに対して行われます。

📝
こちらも以下記事の通り、ANALYSISオプションが予期せぬ結果になりやすいので注意。

具体例

*** サンプルデータ ;
data DT1;
input A$ B @@;
cards;
aaa 10 aaa 20 aaa 30 bbb 40 bbb 50 bbb 60
;
 A  
 B  
 aaa
 10 
 aaa 
 20 
 aaa
 30
 bbb 
 40 
 bbb
 50
 bbb
 60

*** グループ毎に要約行を追加 ;
proc report data=DT1 nowd spanrows;
   column A B;
   define A / order;
   define B / analysis sum;
   break after A / summarize;
run;

分かり辛いですが、4行目と8行目が要約行です。


次回紹介予定のCOMPUTEステートメントを使えば以下のように要約行に「Total」って文字を入れて分かり易くすることも出来ます。

proc report data=DT1 nowd spanrows;
   column A B;
   define A / order;
   define B / analysis sum;
   break after A / summarize;
   compute after A;
        A="Total";
   endcomp;
run;


📝
この方法の注意点は、length以上の値を入れると文字切れしてしまうところ。
今回の例だと変数Aのlengthは$8なので「A="Total"」は入るけど、「A="Total (Summary Line)"」とかってすると、$8をオーバーしているので先頭8バイトで文字切れして「"Total (S"」と出力されます。



おまけ

PAGEオプションを指定するとグループ毎に改ページを挿入できます。

proc report data=DT1 nowd spanrows;
   column A B;
   define A / order;
   define B / analysis sum;
   break after A / page;
run;




REPORTプロシジャ入門記事一覧

1.基本構文【COLUMN, DEFINE】
2.ヘッダーの設定
3.並べ替え・グループ化【ORDER, GROUP】
4.集計【ANALYSIS】
5.転置集計【ACROSS】
6.要約行の追加【BREAK, RBREAK】
7.計算項目の追加【COMPUTE】
8.書式の設定【STYLE=】
9.特定セルの書式設定【CALL DEFINE】
10.数値変数の落とし穴

2015年11月25日水曜日

REPORTプロシジャ入門5:転置集計【ACROSS】



「ACROSSオプション」 を使うと、集計結果を横に転置したような形で出力することができます。



構文

  DEFINE   変数名  /  ACROSS ;

📝
ACROSSオプションは、ORDER・GROUPオプションと同様、欠損値のオブザベーションが除外されたり、並び順がおかしくなる注意点もあるので以下記事も要確認。



サンプルデータ

data DT1;
input A$ B C @@;
cards;
aa 10 11  bb 20 22  aa 10 22  aa 10 11  bb 20 22
;
 A  
 aa
 10 
 11 
 bb 
 20 
 22 
 aa
 10
 22
 aa 
 10 
 11 
 bb 
 20 
 22 



簡単な例

proc report data=DT1 nowd;
  column A;
  define A / across ;
run;

Aの値「aa」「bb」を横に並べて、各値の度数を出しています。


以下のように複数の変数を横に並べることも可能。

proc report data=DT1 nowd;
  column A B;
  define A / across ;
  define B / across ;
run;



変数のネスト

COLUMNステートメントにカンマ「 , 」を入れると変数をネストして度数集計することが可能。

proc report data=DT1 nowd;
  column A , B;
  define A / across ;
  define B / across ;
run;

AとBの組み合わせの度数を求めています。


また以下のように、変数をカッコ囲むと、ネスト先で横に並べることができます。

proc report data=DT1 nowd;
  column A , (B C);
  define A / across ;
  define B / across ;
  define C / across ;
run;

AとB, AとCの組み合わせの度数を求めています。



ちなみに、ANALYSISオプションを用いて度数以外の集計も可能。

proc report data=DT1 nowd;
  column A , B;
  define A / across ;
  define B / analysis sum ;
run;

Aの値毎にBの合計値を求めています。



クロス集計

proc report data=DT1 nowd;
  column A B;
  define A / group ;
  define B / across ;
run;

GROUPとACROSSを組み合わせて、クロス集計が出来ます。





REPORTプロシジャ入門記事一覧

2.ヘッダーの設定
3.並べ替え・グループ化【ORDER, GROUP】
5.転置集計【ACROSS】

2015年11月18日水曜日

REPORTプロシジャ入門4:集計【ANALYSIS】


DEFINEステートメントの 「ANALYSISオプション」 を使うと集計ができます。




構文

DEFINE  変数名  /  ANALYSIS  統計量  ;

※ 統計量 … N, MEAN, MAX, MIN, MEDIAN, STD, STDERR, SUM、、、など




サンプルデータ

data DT1;
input NO$ A @@;
cards;
002 20  002 40  001 10  001 30  . .
;

 NO  
 A  
 002
 20 
 002 
 40 
 001
 10
 001 
 30 
  
 . 




① 単純な集計

proc report data=DT1 nowd;
   column  A;
   define  A    / analysis sum ;
run;



② グループ毎の集計

proc report data=DT1 nowd;
   column  NO A;
   define  NO  / group ;
   define  A    / analysis sum ;
run;

📝
GROUPオプションは欠損値のオブザベーションが除外されたり、並び順がおかしくなる注意点もあるので以下記事も要参照。


③ ひとつの変数に対して複数の統計量を求める


以下は変数Aに対して、合計と平均を求めています。

proc report data=DT1 nowd;
   column  A  A=A2;
   define  A    / analysis sum "合計" ;
   define  A2  / analysis mean "平均値" ;
run;


以下のように同じ変数を複数のDEFINEステートメントに指定することは出来ません。

   define  A  / analysis sum "合計" ;
   define  A  / analysis mean "平均" ;

なので、COLUMNステートメントにて「A=A2」と書いて、A2というAの別名をつくり、

2015年11月17日火曜日

区切り文字をつけて変数値同士を結合する【CATX関数】



「文字変数」区切り文字つきで結合」する方法を紹介。



data DT1;
   length  A B C D $5.  VAR1 $30.;
   A = "aa";
   B = "bb";
   C = "";
   D = "dd";

   * 区切り文字をつけて文字変数の値を結合 ;
   VAR1 = catx( "," , A, B, C, D ) ;
run;

A
 B 
  C  
 D 
 VAR1 
  aa  
  bb  
  
  dd 
  aa,bb,dd 


CATX関数は変数値を区切り文字つきで結合してくれます。


構文


  CATX( "区切り文字" , 変数1, 変数2, ・・・ )



ポイント
  • 変数値の先頭か末尾に半角スペースがある場合は、それらを削除してから結合する。
  • 文字変数が欠損値の場合は、その変数はスキップされる (区切り文字もつかない)。
    • 上の例では、Cが欠損値なので「aa,bb,,dd」ではなく「aa,bb,dd」となります。


2015年11月12日木曜日

REPORTプロシジャ入門3:並べ替えとグループ化【ORDER, GROUP】




サンプルデータ

data DT1;
input NO$ NO2$ A @@;
cards;
002 1 10  002 1 20  002 2 30  002 2 40
001 1 50  001 1 60  001 2 70  001 2 80  . . .
;





行の並べ替え

proc report data=DT1 nowd spanrows;
   column  NO NO2 A;
   define  NO  / order ;
   define  NO2 / order ;
   define  A   / display ;
run;



ORDER を指定した変数で行を並べ替えます。

ポイント
  • 以下のように、ORDER変数で同じ値が繰り返す部分は空白表示になる(左から2つ目の表)
  • この部分は「SPANROWS」で、単一のセルにまとめられる(左から3つ目の表。このオプションはODS出力の種類によってサポートされていなかったり、挙動が異なるので注意)

  • ORDER変数の元々の格納値が欠損値だと、その行は出力から除外される(欠損値の行も出力する方法は下のほうで解説)



行のグループ化

proc report data=DT1 nowd spanrows;
   column  NO NO2;
   define  NO  / group ;
   define  NO2 / group ;
run;



GROUP を指定した変数でグループ化(組み合わせ毎に1行化)します。

ポイント
  • ORDERのところで説明したポイントと同じ
  • あと、同じPROC REPORT内で、GROUP変数のほかにDISPLAY変数も設定した場合、グループ化出来ない&NOTEメッセージが表示されるので、取り扱い注意!



欠損値の出力


ORDER, GROUP,(あと別記事で解説しているACROSS)を指定した変数の元々の格納値が欠損値だと、その行は出力から除外されます。

以下2つの方法で欠損値の行も出力可能です。


方法1

PROC REPORTステートメントに「MISSING」を指定する。
この方法は、PROC REPORT内の全ORDER, GROUP, ACROSS変数に対して効力がある。

proc report data=DT1 nowd spanrows missing;
   column  NO NO2 A;
   define  NO  / order ;
   define  NO2 / order ;
   define  A   / display ;
run;




方法2

DEFINEステートメントに「MISSING」を指定する。
この方法は、MISSINGを指定したDEFINEステートメント内のみに効力がある。

proc report data=DT1 nowd spanrows;
   column  NO NO2 A;
   define  NO  / order missing;
   define  NO2 / order missing;
   define  A   / display ;
run;

(気をつけたいのが、例えばX, YというORDER変数があったとして、XにはMISSINGを指定して、Yには指定しなかった場合、、Xの格納値がなんであろうと、Yの元々の格納値が欠損値だとその行は出力から除外されます)



注意点


SASのマニュアルに今後のリリースで設定を変更するかもという注意があったので、2015/11/12時点での話になりますが、ORDER, GROUP, ACROSSを指定した変数は「ORDER=FORMATTED」という、データの並べ替えの方法が裏で設定されていて、これがちょっと混乱を招くおそれがあります。

以下記事をご覧ください。

2015年11月10日火曜日

REPORTプロシジャ入門2:ヘッダーの設定


ヘッダーを自分なりにカスタマイズする方法を紹介。



サンプルデータ

data DT1;
input NO$ A B;
cards;
001 1 4
002 2 5
003 3 6
;



【その1】 ヘッダーの指定

proc report data=DT1 nowd ;
   column NO A B;
   define  NO /  display  "項目1" ;
   define  A    /  display  "項目2" ;
   define  B    /  display  "項目3" ;
run;

(※ヘッダーを指定しないと、変数ラベルまたは変数名が表示されます)



【その2】 ヘッダーを改行する

proc report data=DT1 nowd split="#";
   column NO A B;
   define  NO /  display  "項目#1" ;
   define  A   /  display  "項目#2" ;
   define  B   /  display  "項目#3" ;
run;

  • SPLIT="半角文字"」で指定した半角文字をヘッダーの改行用文字に設定できます。
  • SPLIT=を指定しないと、デフォルトでスラッシュ「/」が改行用文字になります。
  • ODS出力の種類(LISTING, HTML, RTFなど)によって、ヘッダー部分のみに機能したり、データ部分にも機能したりと挙動が異なるので、各自で挙動確認した方が良いです。


【その3】 ヘッダーを2段にする

proc report data=DT1 nowd;
   column  NO  ("ああ" A B) ;
   define  NO /  display ;
   define  A   /  display ;
   define  B   /  display ;
run;


構文
COLUMN   ( "ヘッダー"   変数名1  変数名2 ・・・ ) ;

  • まず2段にしたい部分をカッコで囲みます。
  • ヘッダーを指定することで1段追加することができ、
  • 変数名を指定することで、次の段に変数を並べる事ができます。


応用
以下のように、カッコをネストする事も可能。
proc report data=DT1 nowd;
   column  NO  ("ああ"  ("いい" A)   ("うう" B)  ) ;
   define  NO /  display ;
   define  A   /  display ;
   define  B   /  display ;
run;


さらに書式などを細かく設定するにはSTYLE=オプションというものがあり、別記事で紹介予定。



REPORTプロシジャ入門記事一覧

2.ヘッダーの設定
3.並べ替え・グループ化【ORDER, GROUP】

2015年11月5日木曜日

REPORTプロシジャ入門1:基本構文【COLUMN, DEFINE】





REPORTプロシジャは、データセットの中身を出力するPRINTプロシジャの拡張版みたいなやつです。




基本構文

PROC REPORT   DATA=データセット名  NOWD ;
       COLUMN   変数名1 変数名2 変数名3 ・・・ ;

       DEFINE     変数名1  /  オプション ;
       DEFINE     変数名2  /  オプション ;
       DEFINE     変数名3  /  オプション ;
       ・・・ 
RUN;

  • NOWD    …  これを指定しないと余計な画面が出てしまう(SAS9.4からNOWDがデフォルト)
  • COLUMN … 出力する変数名を列挙。
  • DEFINE   … COLUMNで指定した変数へのオプションを指定






* サンプルデータ ;
data DT1;
input NO$ A:yymmdd10.;
cards;
001 2015/01/01
002 2015/01/02
003 2015/02/10
;

* PROC REPORT ;
proc report data=DT1 nowd;
    column NO A;
    define NO  /  display  ;
    define A    /  display  f=yymmdd10.;
run;


  • 変数の値を集計したりグループ化したりするのではなく、そのまま使いたい場合は、DEFINEステートメントにDISPLAYオプションをつける。
  • フォーマットを当てて出力する場合は、DEFINEステートメントにFORMAT=(またはF=)オプションをつける。



REPORTプロシジャ入門記事一覧

2015年11月2日月曜日

CLASSステートメントは分割して書ける


CLASSステートメントが使えるプロシジャ全てに対応している機能か不明(使えてもリファレンスに詳細が記載されていないものがある)なので、
今回は、リファレンスにも詳細記載しているMEANSプロシジャで解説していきます。


サンプルデータ

* Sample data ;
data DT1;
input A B VAL;
cards;
1 1 10
2 1 15
. 1 12
. . 13
;
 A  
 B  
 VAL  
  1    1  10
  2    1  15
  .    1  12
  .    .  13



CLASSステートメントの分割


以下よくあるプログラムですが、、、
proc means data=DT1;
  var VAL;
  class A B;
run;


CLASSステートメントを分割して書くことが出来る。
proc means data=DT1;
  var VAL;
  class A;
  class B;
run;


分割して書けるから何なの?って感じですが、
以下のように「CLASS変数の一部にオプションを適用させたいとき」に便利です。

proc means data=DT1;
  var VAL;
  class A / descending;
  class B;
run;

上の例では、変数Aのみ降順に出力するよう descendingオプションを設定しています 。



ちょっとした注意点

以下では変数Aだけmissingオプションをつけて、欠損値のものも分類として出力させています。

proc means data=DT1;
  var VAL;
  class A / missing;
  class B;
run;



ただし、たとえAが欠損値でも、missingオプションを適用させていないB も欠損値であれば、分類として出力されません。(サンプルデータ4行目)

 A  
 B  
 VAL  
  1    1  10
  2    1  15
  .    1  12
  .    .  13


その他

TABULATEプロシジャはCLASSステートメントを使いまくるので、今回の方法が役に立つと思います。


2015年10月27日火曜日

PUT (変数名) (出力時の表示法) という書き方





PUTステートメントで、変数値をログや外部ファイルに出力することができます。
今回はこのPUTステートメントの便利な書き方を紹介します。



以下の構文で、指定した変数すべてに、出力時の表示法を設定できます。

構文
PUT  (変数名1 変数名2 ・・・) (出力時の表示法) ;

または全変数(自動変数以外)を出力対象にしたい場合は

PUT  (_ALL_) (出力時の表示法) ;



例1
data DT1;
  A=1;
  B=2;
  put (_ALL_) (=);
run;

ログ
A=1 B=2

変数にイコール「=」をつけて出力


例2
  put (_ALL_) (=/);

ログ
A=1
B=2

変数にイコール&改行をつけて出力


例3
  put (_ALL_) (+0);

ログ
2

変数値のみ出力


この使い方を覚えてると、ここぞという時にも便利です。

2015年10月22日木曜日

順位をつけるRANKプロシジャと、TIESオプションによる同値の扱い【まとめ】





変数値の小さい順に、順位を与える事ができます。



構文

PROC  RANK   DATA = 読込データ  OUT = 出力データ  TIES = タイ値の扱い ;
      VAR          順位を見る変数 ;
      RANKS     順位を格納する変数 ;
RUN ;



注意点


  • 欠損値には順位がつかない。
  • RANKSを指定しないと、VARの変数に順位が格納される(上書きされる)。
  • 同値があった場合の取り扱いを、TIESオプションで設定。
  • 以下で紹介されている「浮動小数点の誤差」ってやつで微妙に値が異なっていると、別々の順位が割り当てられるのでご注意ください。


具体例


サンプルデータ
data DT1;
input A @@;
cards;
10 10 21 30
;
  A  
  10  
  10
  21
  30


TIESオプションの設定別
proc rank data=DT1 out=OUT1 ties=low;
   var A;
   ranks A2;
run;
  A  
  A2  
  10    1  
  10  1
  21  3
  30  4

1位と2位が同値なので、最小の1位が入る。
次の値が3位


proc rank data=DT1 out=OUT2 ties=high;
   var A;
   ranks A2;
run;
  A  
  A2  
  10    2  
  10  2
  21  3
  30  4

1位と2位が同値なので、最大の2位が入る。
次の値が3位


proc rank data=DT1 out=OUT3 ties=mean;
   var A;
   ranks A2;
run;
  A  
  A2  
  10    1.5  
  10  1.5
  21  3
  30  4

1位と2位が同値なので、平均の1.5位が入る。
次の値が3位


proc rank data=DT1 out=OUT4 ties=dense;
   var A;
   ranks A2;
run;
  A  
  A2  
  10    1  
  10  1
  21  2
  30  3

1位と2位が同値なので、1位が入る。
次の値が2位になる。



ちなみに、値が大きい順に順位をつけたい場合は、descendingオプションをつけます。

proc rank data=DT1 out=OUT5 ties=dense descending;
   var A;
   ranks A2;
run;
  A  
  A2  
  10    3  
  10  3
  21  2
  30  1




2015年10月20日火曜日

大文字や小文字に変換する関数


  • 半角文字 → 文字に変換 ・・・ UPCASE関数
  • 半角文字 → 文字に変換 ・・・ LOWCASE関数





data DT1;
   length A A2 B B2 $10.;
   A = "abcdefg";
   A2 = upcase(A);

   B = "ABCDEFG";
   B2 = lowcase(B);
run;


2015年10月19日月曜日

最初の1バイト目だけ大文字に変換する


たとえば「abc def」→「Abc def」のような変換です。


前提条件
・ 最初の1バイト目はアルファベットである事。
・ 対象変数は半角の英数記号のみである事。


サンプルデータ

data DT1;
   length VAL $20.;
   VAL="proc print"; output;
   VAL="data step"; output;
run;

 VAL  
  proc print  
  data step



先頭の1バイト目だけ大文字にする

data DT2;
   length VAL2 VAL3 $20.;
   set DT1;

   * ① SUBSTR関数を使う ;
   VAL2 = upcase(first(VAL)) || substr(VAL,2);

   * ② 正規表現を使う ;
   VAL3 = prxchange('s/(^[a-z])/\U$1/', 1, VAL);
run;

 VAL2  
 VAL3  
 VAL  
 Proc print Proc print  proc print 
 Data step  Data step  data step

① SUBSTR関数を使う方法
FIRST関数は1バイト目を抜き出す関数
つまり1バイト目を抜き出して大文字にしたものと、2バイト目以降の文字を結合しています。

② 正規表現を使う方法
PRXCHANGE関数で正規表現による置換をしてます。
「prxchange('s/(^[a-z])/\U$1/', 1, VAL)」

(^[a-z])」は先頭の文字がa~zのいずれかである場合、、という意味。
\U$1」は上記を大文字に変換しています。