2014年7月17日 星期四

以Batch 模式執行SAS的簡便語法


=====================================================
:SAS Batch 檔輸出,這裡可寫說明
:以下設定參數代表的意義
set src=C:\
set code=test_pgm.sas
set log=C:\
set prt=C:\
:以下為呼叫SAS的指令
"C:\Program Files\SASHome\x86\SASFoundation\9.3\sas.exe" -nologo -nosplash -sysin "%src%%code%" -print "%prt%" -log "%log%"
exit
=====================================================

注意事項:

  1. 要使用,請將上面線內的語法貼到notepad裡,並將副檔名存成 batch。
  2. set的部分,src,log,prt分別是在設定sas語法、log、output存放的路徑,而 code則在指定sas語法檔名
  3. 最後一段SAS指令的部分為完整的一列,就是在同一列裡,中間並沒有用Enter換行。而 -sysin 之後立馬要接sas語法檔的詳細路徑。-print 與 -log 若不指定路徑,預設會出現在含有 sas.exe 的資料匣裡。




參考來源:
http://forum.slime.com.tw/thread136868.html
https://communities.sas.com/message/107052

2014年7月10日 星期四

常用的資料整理程式

/*依 ID,Merge 兩個資料檔 ,再依某變項 (cmdecod),保留唯一的值*/

/*方法一*/
DATA t ; merge cm(in=a )  treat ; by subjid  ;  if a ;
run;
proc sort data=T    nodupkey out=t3;
by subjid cmdecod;
run;

/*方法二*/
DATA t ; merge cm(in=a )  treat ; by subjid  ;  if a ;
run;
data t2  ; set t ; by subjid cmdecod;
if first.cmdecod;
run;

/*方法三*/
proc sql
   noprint;
   create table cmtosum as
      select unique (c.cmdecod) as cmdecod, c.subjid, t.trtcd
         from cm as c, treat as t
         where c.subjid = t.subjid
         order by subjid, cmdecod;
quit;


/*依組別(藥名),把資料檔由直向拉成橫向*/

/*方法一*/
Proc sort    data = counts;       by cmdecod trtcd; run;
Data cc2 ; set counts; by cmdecod trtcd;
/*記住3個變項值,不然數據長成一斜線*/
Retain n1-n3;
/*新組別時,先清空數據*/
Array nn {3} n1-n3;
   if first.cmdecod then do i =1 to 3;
nn{i}=.;
   end;
/*指定數值,亦可用Array的方式 nn{trtcd} ,但本例 trtcd有missing,固改用 if then 的方式*/
  if trtcd=. then n1=frequency;
  if trtcd=0 then n2=frequency;
  if trtcd=1 then n3=frequency;
/*輸出每組的最後一筆*/
if last.cmdecod;
run;

/*方法二*/
Proc sort    data = counts;  by cmdecod trtcd; run;
/*利用 Merge ,分組別進行*/
Data cm;
   merge counts(where = (trtcd = 1) rename = (frequency = count1))
         counts(where = (trtcd = 0) rename = (frequency = count2))
         counts(where = (trtcd = .) rename = (frequency = count3))
         end = eof;
      by cmdecod;
run;

/*方法三*/
/*較不建議,若是 ID 的變項值為 missing ,資料會被刪除*/
Proc transpose data=counts prefix=nn out=cc ;
by cmdecod ; id trtcd;
var Frequency;
run;




部分程式引用,Ref:  Jack Shostak, SAS Programming in the Pharmaceutical Industry.

2014年7月9日 星期三

常用的Macro

/*資料筆數存成 Macro Variable*/
/*方法一*/
Proc Sql noprint;
/*Macro Variable N1 */
select Count ( Distinct subjid ) format=3.
into :N1
      from treat
      where trtcd = 1;

 /*Macro Variable N2 */
select count(distinct subjid) format = 3.
      into :n2
      from treat
      where trtcd = 0;
Quit;
%put &N1 &N2;

/*方法二*/
data _null_;
   set treat end = eof;
   **** 分組的 COUNTER 並 retain 住;
   if trtcd = 1 then
      n1 + 1;
   else if trtcd = 0 then
      n2 + 1;
   **** 總 COUNTER.;
   n3 + 1;
   **** 資料最後一列即為所要的數值;
   if eof then
      do;  
         call symput("n1", put(n1,3.)); *用 PUT 數值轉為文字;
         call symput("n2", put(n2,3.));
         call symput("n3", put(n3,3.));
      end;
run;


/*一組變項定義為 Macro Variables*/
/*方法一 用 Arrary*/
DATA A;
Array Vars {8} $18.     (
'Dis_hypertension'
'Dis_DM'
'Dis_hyperlipidemia'
'Dis_stroke'
'dis_asthma'
'Dis_Kidney'
'Dis_HD'
'Dis_osteoporosis'
)  ;
Do i =1 to 8;
Call symput (  'I_num'  , compress(i)  );
Call symput (  'Vv'||compress(i) , Vars{i}  );
End;
run;
%Put   &I_num;
%Put &Vv1 &Vv2  &Vv8 ;

/*方法二 用資料檔處理的方式*/
%LET Text=  那一整群變項;
/*以變項群建立新資料檔(橫向)*/
DATA M_LIST ; input &text;   run;
/*讀 sashelp.Vcolumn取得資料檔訊息(直向)*/
Proc Sql;
Create Table M_LIST2  AS Select Name as MVAR_LIST   From sashelp.Vcolumn
Where libname='WORK' and memname='M_LIST' ;
Quit;
/*以及變項群數目*/
Proc Sql noprint;
Select nvar into :Num  From Sashelp.Vtable
Having libname='WORK' and memname='M_LIST' ;
Quit;
/*巨集變項名稱 Var1,  Var2, ~ VarN */
DATA M_Vars  (Keep= MVAR_PRE);
Pre='Var' ;
do i=1 to &Num;   MVAR_PRE=Pre||compress(i);  output;  End;
run;
/*Macro name 與 變項群 MERGE,Symput為 Macro Variable*/
DATA _NULL_  ; Merge M_vars M_list2 ;   Call Symput ( MVAR_PRE, MVAR_LIST);  run;