顯示具有 Put 標籤的文章。 顯示所有文章
顯示具有 Put 標籤的文章。 顯示所有文章

2014年4月27日 星期日

建構變項—SAS Funtion

function-name(argument-1<,argument-n>);

  • mean(x1,x2,x3)
  • mean(of x1-x3)
    • mean(x1-x3)變成 x1-x3 的平均
  • mean(of narray{*})

 

文字與數值之間轉換

  • 多數的function使用時,系統可自行轉換,建立一個暫時變項,但遇到 $ , 等情況會失效
  • Input 可 Character-to-Numeric Conversion
    • INPUT(source, informat)
      New=Input ( ID ,  4. )
  • Put 可 Numeric-to-Character Conversion
    • PUT (source,format)
      • Fee_lv2=put( fee, 3.);
      • Fee_lv2=put( fee, fee.);
      • Fee_lv=input(  put( fee, fee.),  $10. );

========================
與 Date Value 有關的 function
========================

  • now1=mdy(4,27,2014); format now1 date9.;
    now2='27Apr2014'd;    format now2 date9.;
  • now3=today(); format now3 mmddyy10.;
    now4=date(); format now4 mmddyy8.;
  • nowtime=time(); format nowtime TIME8.;
    nowtime2='27Apr2014:15:35:00'dt; 
    format nowtime2 datetime.;

now1=
mdy(4,27,2014);

不正確的用法
mdy(Apr,27,2014);
mdy(‘Apr’,27,2014);

format now1 date9.;

27APR2014

now2=
'27Apr2014'd;

format now2 date7.;

27APR14

now3=today();




now4=date();

format now3 mmddyy10.;

format now4 mmddyy8.;

04/27/2014

04/27/14

nowtime=time();

format nowtime TIME8.;

15:35:17

nowtime2=
'27Apr2014:15:35:00'dt;

format nowtime2 datetime.;

27APR14:15:35:00

 

  • day=day(now1); /*27APR2014*/
    27
    month=month(now1);
    4
    year=year(now1);
    2014
  • qtr=qtr(now1);
    2
  • weekday=weekday(now1);
    1 /*日一二三四五六*/

 

  • 時間間隔
    INTCK('interval',from,to) 
    INTCK ( 'day' , '31dec2013'd , '01jan2014'd );
    常用於算周年
    • Day  經過幾個日數----------  1日
    • Week 經過幾個Sunday ----- 0個 Sunday
      • from為周日,to為周一,則0個Sunday
      • from為周六,to為周日,則1個Sunday
    • Month 經過幾個某月1日------1個某月1日
    • Year 經過幾個1月1日---------1個1月1日
      • Years = intck ( ‘year’, First_meet, Today() );

 

    • 時間推移
      INTNX('interval',startfrom,
                             increment<,'alignment'>)
      'alignment' 可為 b m e s,用於 month較易懂,其他interval 的不是很懂
      • Month
        • MonthX=intnx ('month','27apr2014'd, 5 , 'alignment' );
          推 5個月,b m e s的結果依序為
          01SEP2014月初
          15SEP2014月中
          30SEP2014月尾
          27SEP2014同日

 

日期之差

  • DATDIF(start_date,end_date,basis)
    • basis 有
      '30/360'   'ACT/ACT' 
  • YRDIF(start_date,end_date,basis)
    • basis 有
      '30/360'   'ACT/ACT'   'ACT/360'   'ACT/365'

 

=========================
與 文字 有關的 function
========================

傳出變項裡的字串,或者取代字串

  • SCAN(argument,n<,delimiters>)
    • 依 delimiter 區分,來選字第n個字,leading delimiters have no effect,預設的delimiter 有
      blank . < ( + | & ! $ * ) ; ^ - / , %
    • SCAN產生的新變項預設為 $200. 
      最好先設定 LENGTH
    • 新變項=scan (Name , 2,  ' -'  );
      delimiter 是 空白 與 -
    • 新變項=scan (Name , 2,  '-'  );
      delimiter 只有 -  
  • SUBSTR (argument, position <,n>)
    n表示連著取n個字元,不指定 n 就是position之後全要了。數值變項,請先Put成文字變項。
    • 依 position 來選字
      • First=Substr ( name , 1, 5) ;
    • 依 position 來取代文字,類似 TRANWRD
      • Substr ( name , 1, 5  ) ='First';
      • 有意義一點的作法是
        IF Substr ( name , 1, 1  ) = 'M'
             then Substr ( name , 1, 2  ) ='W%';
        注意新增的文字的 n 要對,本例為2個字元。
  • TRANWRD(source,target,replacement)
    搜查特定文字,並取代該文字。記得設定 length
    • Nname=TRANWRD ( name , 'M' ,  'W%' );

 

刪除多餘空白

  • TRIM(argument)
    刪除trailing blanks,用於組合文字
    新變項的length有可能多於實際文字量,因此還是會有trailing blanks
    • new=trim(Lastname) || ', ' || trim(location) || ', ' || trim(phone) ;
  • CATX(separator,string-1 <,...string-n>)
    • 用於連結字串,移除 leading and trailing blanks, 插入分隔符號( separator)。
      相當於TRIM and LEFT 的組合
    • new2=catx ( ', ' , Lastname, location, phone);

 

找字串的Position

  • INDEX(source,excerpt)
    搜尋特定字串(case sensitive),並回傳找到第一個的位置,若找無就是0
    • n1=INDEX (Lastname,'LA') ;
  • FIND(string,substring<,modifiers><,startpos> )
    用途與INDEX相近
    • n2=Find (Lastname,'LA') ;

 

大小寫文字的轉換

    • UPCASE(argument) 全大寫
    • LOWCASE(argument) 全小寫
    • PROPCASE(argument<,delimiter(s)>) 依分隔點區分,首字元大寫

 

========================
與 數字 有關的 function
========================

INT(argument) 取整數部分

ROUND(argument,round-off-unit) 類似四捨五入

  • d1 = round(1234.56789,100)     - 1200;
    d2 = round(1234.56789,10)      - 1230;
    d3 = round(1234.56789,1)       - 1235;
    d4 = round(1234.56789,.1)      - 1234.6;
    d5 = round(1234.56789,.01)     - 1234.57;
    d6 = round(1234.56789,.001)    - 1234.568; 
    d7 = round(1234.56789,.0001)   - 1234.5679;
    d8 = round(1234.56789,.00001)  - 1234.56789;

2014年4月21日 星期一

數字轉文字並保留小數位數

/*數字轉文字並保留小數位數 Converting a Numeric Variable to a Character Variable*/
data tt;
b=131.19;
b1=compress(b);
b2=put(b,6.2);
a=130.00;
a1=compress(a);
a2=put(a,6.2);
run;
image
之前都用 compress的方式,但最大問題是剛好整數(130.00)會變成130!有想過以 length 取得長度,但數值的長度與是否為整數無關,一開始指定best12. ,該欄下的所有 length 就都是12。
因此改用 put 最方便,PUT always return a character
其中參數6.2是指先保留6個位元,其中含兩位小數,輸出後的文字總長即為6位元。

2014年4月20日 星期日

Reading Raw Data File

指定外部資料檔的位置,與讀檔
  • SAS系統檔,Libname
    libname NHIS 'c:\report';
  • 其他檔案,Filename
    • 單檔 filename nhis "z:\DATA\admit.txt";
      nhis 代表實體檔案
      • DATA work.admit;
            infile nhis delimiter='09'x MISSOVER DSD  firstobs=2;
            input ....;
      • filename nhis clear;
    • 多檔 Filename NHIS2 'c:\report\';
      • DATA work.admit;
            infile nhis2(admit.txt) delimiter='09'x MISSOVER DSD  firstobs=2;
            input...;
    • 直接呼叫檔案
      • DATA work.admit;
            infile "z:\DATA\admit.txt" delimiter='09'x MISSOVER DSD  firstobs=2;

Column Input
  • INPUT variable <$> startcol-endcol . . .;
    適用於 Fixed-field Records
    • 條件:固定的n個變項,變項為標準的數字與文字,原始資料要按位子對齊好。
    • 指定變項的起點與終點,因此,變項間的順序就不重要了。資料欄位也可被重覆讀取。
  • 用 Infile 
    • libname libref 'SAS-data-library';
      filename nhis "z:\DATA\admit.txt";
    • DATA work.admit;
    • infile "z:\DATA\admit.txt" obs=10 ;
    • input ID 1-10 Name $ 20-30 Sex 15;
    • run;
  • 用 Datalines (Reading Instream Data )
    • DATA work.admit;
    • input ID 1-10 Name $ 20-35 Sex $ 15;
    • DATALINES;
    • 2458          F    Murray, W
    • 2462          M    Almers, C
    • ;
    • 不必再 run
  • Datalines 換行讀取  (僅讀入部分變項)
    • data coat;
    • input category high1-high3 / low1-low3;
    • datalines;
    • 5555 9 8 7 6
    • 4 3 2 1
    • 8888 21 12 34 64
    • 13 14 15 16
    • ;
  • DATA ERROR訊息,不會中斷DATA STEP。

Formatted Input
  • 適用於 Fixed-field Records standard and nonstandard data
    @ n 與 + n  可以交互使用
  • INPUT @n Var-name Informat. ;
    n表示第幾個欄位(position)起
    • input @15 ID $5. @1 LastName $10. @30 Payment 8.
  • INPUT +n Var-name Informat.;
    用+n 要加到變項的起點,要注要讀完一個變項後,column pointer 會自動往後一位,LastName 在第10位End,到第15位的ID時,要 +4 就可以了。
    往回讀資料,要用  + (-n)
    • input LastName $10. +4 ID $5.  +10 Payment 8.
  • Informat 告知 SAS 原始資料的儲存方式,才能順利讀取檔案,但是在 PDV裡,變項不自動以 informat指定格式儲存。
    • PERCENTw.d      w為總長,d為小數位數
    • COMMAw.d
      • 適用在數值卻有  , $ %   等符號 
    • date7.         date9.
      mmddyy8.   mmddyy10.
      datetime.
      TIME8. 

Record Formats
Raw data 儲存observation的方式
  • Fixed-Length Records
    每筆的 end of record marker 都在同一位置 
  • Variable-Length Records
    不固定的 end of record marker
    • 有fixed-field data的,某區段都固定給某變項,例如欄位長固定( 4.)
      PAD option
      • 有些筆數的值較短(ex: 10,還有兩個位元),會提早遇到end of record,避免電腦傻傻執意要換到下列補足長度(另2位元)
      • 本欄為 missing

Free-Format Data
欄位的 begin 與 end 沒有完全固定position
  • List Input與Delimiter(DLM)
    raw data file的限制:數字與文字都只能 8位元,超過會 truncated;標準變項;以空白或符號分隔變項;文字或數字裡不能有該符號;missing要用 . 或其他文字表示。
    • Infile "z:\DATA\admit.txt" DLM=’符號’
      Input
      var1 var2
      var3-var6 
      (var7-var10) ($)   ….. varN ;
  • 解決方案
    • MISSOVER option:某列尾端有Missing value
    • DSD option:某列開頭、列中有missing value
      • 預設Delimiter 為 , 
      • ,, 表示 missing
      • 值的引號”會被移除
    • Length statement:文字大於8位元
      • Infile ….; Length Var $20. ; input Id Var …..;
        注意此時Input裡的 Var 不必再加 $ 了。但因為先以 Length設定,Var是第一個變項,而非 Id
    • & 文字值含有空白(不連續),如 Taipei city
      • 其後的Delimiter 要改為兩個空白「  」
      • Length City $ 12; Input …  city & ;
        或 Input … city & $12. ;
    • : 數值或文字長度超過8,且不內含空白
      • 文字時,需設 Length
      • 數值時,不需設 Length,用 Comma. 即可
        • input name: $13.  pop: Comma.  ;
          datalines;
          TaipeiCity 100,000,000
          KeelungCity 100000000
          ;

讀 Excel 檔
  • libname libref 'location-of-Excel-workbook' <options>;
    • libname readxls "Z:\DATA\finance.xls";
    • proc contents data=readxls._all_ ; run; *可直接知道sheet細詳資訊;
    • data finance ;  set   READXLS."'1$'"n  ;run;
    • libname readxls clear; *停止連結 xls 檔;
  • 可用的 option 
    • DBMAX_TEXT=n
      單欄文字長度
    • GETNAMES=YES|NO
      第一列為變項名
    • MIXED=YES|NO
      所有資料轉成文字,預設是no
    • SCANTEXT=YES|NO
      以最長的列寬為預設列寬。
    • SCANTIME=YES|NO
      no 只有time 的變項 也用 date9.
      yes 改用 time8.
    • USEDATE=YES|NO
      yes date/time 的變項 用 date9.no  改用 datetime.

標準的與非標準的變項
  • 數值型
    • 標準的: 羅馬數字、小數數字、正負號數字、科學記號(ex: E-notation)
    • 非標準的:內含(%$,)、日期時間、分數、二進位、十六進位

建構變項的OPERATOR
  • arithmetic operator,依優先順序
    • -(負號)、**(指數)
    • 乘除
    • 加減
  • Comparison Operators
    • > < = ^= >= <=
    • in ( 1 ,2 ,3) 或  in ( 1 2 3) 
    • in ( "LINK" , "Value" )
  • Logical Operators
    • AND & ,  OR  | ,  NOT ^ 
      • 用 OR的注意事項
        • if TimeMin<12 or 14; 
          • OR 前後要分開看, 2 一定是 true,本條件形同虛設
        • if TimeMin<12 or TimeMin=14;
          • 會輸出 <12 還有 =14 的。

新增日期、時間變項 (待續補充)
  • 日期(兩位年從1920起至2019)
    •                   Date='01jan2014'd;              Date='01jan14'd;
    • 以上可選  attrib date format=date9.; 或 attrib date format=date7.;
    • 或            attrib date format=mmddyy10.;   attrib date format=mmddyy8.;
                      01/01/2014                                 01/01/14
  • 時間 
    • Time='21:00't;
    • attrib TIME format=TIME8.;  21時0分0秒
  • Datetime
    • DateTime='01jan2014:21:00:00'dt;
    • attrib DateTime format=datetime.;

輸出Raw Data File
  • 把sas dataset 轉成 依 column 對齊的 txt檔
    • data _null_;
    • set sasuser.admit;
    • file "z:\admit_column.txt"; *沒有 file 就 put 到 log裡;
    • Put
    •   ID  4.
    •   @6 Name  15.    /* 用 @ 位置  VAR  長度  比較不會出錯  */
    •   @22 Sex  1.
    • run;
  • Sas dataset 轉成 Free-Format raw data;
    • PUT variable <: format>;
      • file …;  Put ID  Fee: 7.2 ;
    • DLM=’’
      • file … DLM=’,’;
    • DSD
      • file … DSD;
      • 預設Delimiter 為 ,
      • 有 , 的數值,會包在一組雙引號中
    • PROC EXPORT DATA=SAS-data-set;
      OUTFILE=filename <DELIMITER='delimiter'>;
      RUN;
  • 存到 xls 檔的 sheet
    • libname readxls "Z:\DATA\finance.xls";
    • data readxls.admit;
    • set sasuser.admit; *不必用 'admit$'n ;
    • run;

運用filename, PIPE, infile 與 windows語法互動, 參考Back Up with Each Submit and Save Your Sanity
    • filename backup pipe 'dir C:\backup /t:w /a:-d /OD';
    • data backup;
    •  infile backup missover pad length=len;
    •  input @01 line $varying200. len; 
    • run; 
    •