2018年3月27日 星期二

Array的應用

問題:在 data step 中去處理一大串的變項或數值
說明:
用 Array 來處理,基本架構是
array array-name <$> array-elements <(initial-values)>;
array-elements 可以用

  • list 變項名稱,但是大原則是這些 list 要全為 numeric 或 character ,不能 numeric 或 character 混著用
  • special variable, 如 NUMERIC CHARACTER ALL 。 會直接挑 data set 全部的 numeric 或 character 或全部。
  • 上面都會建立實體的 variable ,但 Temporary 則不會,只會放在 Program data vector。

data a; array A {10} ; array nums {3:10} temporary (90, 91,92 ,93 ,94, 95, 96, 40); do i =1 to dim(A); if i<3 then A=i10; else A=i10+nums; end; run;

就不必寫 array 來找

data a; a=40; b=whichn(a, 90, 91,92 ,93 ,94, 95, 96, 40); put a / b ; run;

IMPLICIT SUBSCRIPTING array-name 改成了array-name (n) 的 n 不放 * 不放 數值,並且放了個空變項,這是舊版SAS的用法 DATA AGE_; z=100;put z; array item(z) age1989 age1993 age1996 age1999 age2003 age2007 age2011 age2015(1989 1993 1996 1999 2003 2007 2011 2015); do over item; put item z ; item=item+1000; put item z ; end; RUN;

INVALID INDEX RANGE DATA AGE_; array item() age1989 age1993 age1996 age1999 age2003 age2007 age2011 age2015 (1989 1993 1996 1999 2003 2007 2011 2015); array X(8); ii=1; do until ( ii gt 8); / do until ( ii ge 8); 不行到8就停了 X8就做不出來*/

put "from 1st put   " ii;
x(ii)=item(ii)+1000;    
ii=ii+1;
put "from 2nd put   " ii;

end; RUN;

FUNCTION NAME AS AN ARRAY NAME ARRAY REFERENCED IN MULTIPLE DATA STEPS, BUT DEFINED IN ONLY ONE

ref: Arrays Made Easy An Introduction to Arrays and Array Processing


/Chapter 15 Processing Variables with Arrays/ /* ARRAY array-name ; An ARRAY statement is not an executable statement; it merely defines an array. 全數值變項 或 全文字變項 array test {4} n1 n2 n3 n4; array test [10:13] n1 n2 n3 n4; array test (*) n1- n4; do i=1 to 4 do i=1 to dim(test)
elements 也可用 NUMERIC CHARACTER ALL Temporary 。 資料檔中沒有 element 列出 的變項,會自動建立該變項 不寫element,系統會自行產生新變項。

*/

data test_array; Array L[4] spring summer fall winter; Array K[5] ; run; /Arrays of Character Variables 各變項預設為$8. / array Chars {5} $ 24; /Assigning Initial Values to Arrays/ data test_array; Array L[5] spring summer fall winter all (1 2 3 4 5); Array K[4] Temporary (11 12 13 14 ) ; Array Z [4]; Do i=1 to dim(z); Z[i]= 1000L[i+1] +100L[i] + K[i] ; End; run; /Multidimensional Arrays/ DATA test_array2 ; array new{3,4} x1-x12; /3 rows, 4 columns/ new(2,3)=0; run; /* x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 */

/Referencing Elements of a Two-Dimensional Array/ data finance.quarters(drop=i j); set finance.monthly; array m{4,3} month1-month12; array Qtr{4}; do i=1 to 4; /*當 i=1,M1j 就全進到 PDV了 */ qtr=0; do j=1 to 3; /*j=1,M11加總入qtr1 / qtr+m{i,j}; end; end; run; / month1 month2 month3 month4 month4 month4 month7 month7 month7 month10 month10 month10 / /資料轉秩/ DATA trans; input id spring summer fall winter ; datalines; 100 0 5 10 15 101 20 25 30 35 102 40 45 50 55 103 60 65 70 75 ; data trans2 ; set trans; array contrib{4} spring summer fall winter ; do i =1 to 4; Value=contrib[i]; output; end; run; proc print ; var id i value ;run; / id i Value 100 1 0 100 2 5 100 3 10 100 4 15 101 1 20 101 2 25 101 3 30 101 4 35 */ /quiz/ data coat; input category high1-high3 / low1-low3; array compare{2,3} high1-high3 low1-low3; do i=1 to 2; do j=1 to 3; compare{i,j}=round( compare{i,j} * 1.12 ); end; end; datalines; 5555 9 8 7 6 4 3 2 1 8888 21 12 34 64 13 14 15 16 ; run;

/* 篩選多個變項,是否有某範圍的值 */ data k ; input a1 a2 a3 ; cards; 10 20 99 1 2 20 99 99 99 5 99 99 ;

data k2 ; set k ; Array k (*) a1-a3; DO i = 1 to 3 ; if 0<k(i) <10 then x1=1; if 0<k(i) <10 then x2=sum(X2 , 1 ); if 0<k(i) <10 then x3+1; end; run;


問題: 由大到小 作 iteration 正確:要加 by 數值
do i3 =dim(AGREE) to 2 by -1; end;

一時忘了,用以下就不行,無法反向
do i3 =dim(AGREE) to 2 ; end;

2018年3月14日 星期三

excel方便用

問題:有兩個變項清單,要如何確認A清單所列變項,有在B清單上
說明:
VLOOKUP(B清單,A清單,1,0)
如果有,公式會回傳對得到的變項名稱;如果沒有,回傳 #N/A
搭配 if() 和 isna() 會更好用,讓連不到的回傳空
=IF(ISNA(VLOOKUP(B清單,A清單,1,0)),"",VLOOKUP(B清單,A清單,1,0))