From: Dan Thompson on 1 Apr 2010 16:20 array cns (15,72) c1s1994--c1s2065 c2s1994--c2s2065 c3s1994--c3s2065 c4s1994--c4s2065 c5s1994--c5s2065 c6s1994--c6s2065 c7s1994--c7s2065 c8s1994--c8s2065 c9s1994--c9s2065 c10s1994--c10s2065 c11s1994--c11s2065 c12s1994--c12s2065 c13s1994--c13s2065 c14s1994--c14s2065 c15s1994--c15s2065; array cns_sum (15) c1s_sum c2s_sum c3s_sum c4s_sum c5s_sum c6s_sum c7s_sum c8s_sum c9s_sum c10s_sum c11s_sum c12s_sum c13s_sum c14s_sum c15s_sum; do i=1 to 15; cns_sum(i)=sum(of cns(i,1-72)); end; I also tried, with no luck: cns_sum(i)=sum(of cns(i,1)--cns(i,1));
From: xlr82sas on 1 Apr 2010 16:51 On Apr 1, 1:20 pm, Dan Thompson <dt4...(a)gmail.com> wrote: > array cns (15,72) c1s1994--c1s2065 > c2s1994--c2s2065 > c3s1994--c3s2065 > c4s1994--c4s2065 > c5s1994--c5s2065 > c6s1994--c6s2065 > c7s1994--c7s2065 > c8s1994--c8s2065 > c9s1994--c9s2065 > c10s1994--c10s2065 > c11s1994--c11s2065 > c12s1994--c12s2065 > c13s1994--c13s2065 > c14s1994--c14s2065 > c15s1994--c15s2065; > array cns_sum (15) c1s_sum c2s_sum c3s_sum c4s_sum c5s_sum c6s_sum > c7s_sum c8s_sum c9s_sum c10s_sum c11s_sum c12s_sum c13s_sum c14s_sum > c15s_sum; > do i=1 to 15; > cns_sum(i)=sum(of cns(i,1-72)); > end; > > I also tried, with no luck: > > cns_sum(i)=sum(of cns(i,1)--cns(i,1)); Hi, This is where we need a tool pack of FCMP routines, in the meantime you might want to take a look at However, I think we should all keep R in mind for matrix problems, hopefully SAS will provide a drop down to R like the the one in IML Warner Brothers Studio and Stat Warner Brothers Studio. For a cleaner version of the text below see: /* T003370 ROW AND COLUMN REDUCTION OPERATORS FOR SAS DATASTEP MUTIDIMENSIONA ARRAYS - WILL CONVERT TO FCMP IN VERSION 9.2 http://homepage.mac.com/magdelina/.Public/utl.html utl_tipweb.txt Here is what you will find (macro has not been stress testes, use at your own risk. %Macro UtlSumOf ( Utl_Mat, /* Datastep Matrix */ Utl_Rows, /* Range or Single row ie 2:5, 1:10, 4 */ Utl_Cols /* Range or Single row ie 2:5, 1:10, 4 */ ) / Des="Column and Row Sum Reductions for Two Dimensional Arrays"; /*---------------------------------------------*\ | You have the following Array Statement | | Example : | | Array Mat{2,3} ( 1 2 3 | | 4 5 6 ); | | And you want the Row, Column and Grand Totals| | Data _Null_; | | Array Mat{2,3} ( 1 2 3 | | ColSum1= %UtlSumOf ( Mat,1:2,1); | | ColSum2= %UtlSumOf ( Mat,1:2,2); | | ColSum3= %UtlSumOf ( Mat,1:2,3); | | | | RowSum1= %UtlSumOf ( Mat,1,1:3); | | RowSum2= %UtlSumOf ( Mat,2,1:3); | | | | Total=%UtlSumOf (Mat,1:2,1:3); | | | | Put | | ColSum1= / | | ColSum2= / | | ColSum3= / | | | | RowSum1= / | | RowSum2= ; | | | | Run; | | | | You could use the macro language to simplify| | | | Array Colsum{3}; | | %Do Col=1 %To 3; | | ColSum{&Col}= %UtlSumOf ( Mat,1:2,&Col ); | | %End; | \*---------------------------------------------*/ %Local i j; %If &Utl_Mat. = %Str() or &Utl_Rows. = %Str() or &Utl_Cols. = %Str() %Then %Do; %Put Error User Required Parm Missing; %put Utl_Mat = &Utl_Mat. ; %put Utl_Rows = &Utl_Rows. ; %put Utl_Cols = &Utl_Cols. ; %goto exit; %end; %If %index(&Utl_Rows.,%str(:)) Ne 0 %Then %Do; %Let Utl_Row1st=%qscan(&Utl_Rows.,1,%str(:)); %Let Utl_RowLst=%qscan(&Utl_Rows.,2,%str(:)); %end; %Else %Do; %Let Utl_Row1st=&Utl_Rows.; %Let Utl_RowLst=&Utl_Rows.; %End; %If %index(&Utl_Cols.,%str(:)) Ne 0 %Then %Do; %Let Utl_Col1st=%qscan(&Utl_Cols.,1,%str(:)); %Let Utl_ColLst=%qscan(&Utl_Cols.,2,%str(:)); %end; %Else %Do; %Let Utl_Col1st=&Utl_Cols.; %Let Utl_ColLst=&Utl_Cols.; %End; sum ( of %do i = &Utl_Row1st. %to &Utl_RowLst.; %do j=&Utl_Col1st. %to &Utl_ColLst.; &Utl_Mat.(&i.,&j.) %end; %end; ) %Exit: /* Data _Null_; Array Mat{2,3} ( 1 2 3 2 3 6 ); ColSum1= %UtlSumOf ( Mat,1:2,1); ColSum2= %UtlSumOf ( Mat,1:2,2); ColSum3= %UtlSumOf ( Mat,1:2,3); RowSum1= %UtlSumOf ( Mat,1,1:3); RowSum2= %UtlSumOf ( Mat,2,1:3); Total=%UtlSumOf (Mat,1:2,1:3); Put ColSum1= / ColSum2= / ColSum3= // RowSum1= / RowSum2= // Total=; Run; */ %mend UtlSumOf; Data _Null_; Array Mat{2,3} ( 1 2 3 2 3 6 ); ColSum1= %UtlSumOf ( Mat,1:2,1); /* sum rows 1-2 for column 1 */ ColSum2= %UtlSumOf ( Mat,1:2,2); /* sum rows 1-2 for column 2 */ ColSum3= %UtlSumOf ( Mat,1:2,3); /* sum rows 1-2 for column 2 */ RowSum1= %UtlSumOf ( Mat,1,1:3); / sum row 1 columns 1-3 */ RowSum2= %UtlSumOf ( Mat,2,1:3); / sum row 2 columns 1-3 */ Total=%UtlSumOf (Mat,1:2,1:3); /* sum rows 1-2 and cols 1-3 this is the entire array */ Put ColSum1= / ColSum2= / ColSum3= // RowSum1= / RowSum2= // Total=; Run; /* T003340 CREATE AN DATASTEP ARRAY STATEMENT LIKE 'MAT2X4{2 ,4} ( 64 50 48 51 55 49 48 50 )' FROM PROC FREQ OUTPUT */ * **** **** * * * * * * * * * * * * * * * * * * * * * * * ***** **** **** ***** * * * * * * * * * * * * * * * * * * * * * * * * * * * *; %macro Utl_MkeAry ( Utl_InDsn, Utl_InRowVar, Utl_InColVar, Utl_MacRetVar=Utl_MkeAry ) / Des="Create an Array Statement with Freq counts"; Ods Exclude All; Ods Output Observed=Utl_MkeAry01; Proc Corresp Data=&Utl_InDsn Observer dim=1; Table &Utl_InRowVar., &Utl_InColVar.; Run; Ods Select All; Proc Print Data=Utl_MkeAry01; Run; Proc Print Data=Utl_MkeAry01; Run; %Let Cols=%str(); %Let Rows=%Str(); Data _Null_; /* Get Number of ROws and Columns */ Set Work.Utl_MkeAry01 Nobs=Mobs; Array Cols{*} _Numeric_; Call SymPut('Rows',Compress (Put(Mobs-1,9. ))); Call SymPut('Cols',Compress (Put(Dim(Cols)-1,5.))); Stop; Run; %Put Rows=&Rows; %Put Cols=&Cols; Data _Null_; Length MacStr $32700; Retain MacStr; Set Work.Utl_MkeAry01; Array Cols{*} _Numeric_; If _n_ =1 Then MacStr ="{&Rows.,&Cols.} ( "; Do J= 1 To Dim(Cols)-1; MacStr=Trim(MacStr)!!' '!!Compress(Put(Cols{J},9.)); End; If _n_ =&Rows. Then Do; MacStr=Trim(MacStr)!!' )'; /* do not change anything below this line */ Call Symput(%UnQuote(%Bquote('&Utl_MacRetVar.')),Trim(MacStr)); Stop; End; run /* do not put a semicoln here */ %Exit: %Mend Utl_MkeAry; Data Mat10x8; Do Reps=1 To 100; Do Row=1 To 10; Do Col=1 To 8; If Uniform(5731) > .5 then output; End; End; End; Run; %Utl_MkeAry ( Utl_InDsn =Work.Mat10x8, Utl_InRowVar =Row, Utl_InColVar =Col, Utl_MacRetVar=NumLst ); %put &numlst; run; /* Row _1 _2 _3 _4 _5 _6 _7 _8 Sum 1 64 50 48 51 55 49 48 50 415 2 57 46 58 41 53 49 46 50 400 3 50 48 58 50 55 50 54 50 415 4 46 56 47 45 49 55 52 50 400 5 50 49 56 45 49 52 36 53 390 6 58 54 42 47 45 49 54 40 389 7 54 44 47 45 51 58 55 49 403 8 54 53 49 52 54 54 51 55 422 9 45 42 52 57 49 41 49 48 383 10 52 51 45 50 50 46 43 57 394 Sum 530 493 502 483 510 503 488 502 4011 245 %put &numlst; {2 ,4} ( 64 50 48 51 55 49 48 50 ) 56 47 45 49 55 52 50 50 49 56 45 49 52 36 53 58 54 42 47 45 49 54 40 54 44 47 45 51 58 55 49 54 53 49 52 54 54 51 55 45 42 52 57 49 41 49 48 52 51 45 50 50 46 43 57 ) */ Data RowColSum; Array Mat10x8 &NumLst. ; ColSum1= %UtlSumOf ( Mat10x8,1:10,1); RowSum1= %UtlSumOf ( Mat10x8,1,1:8); TotSum= %UtlSumOf ( Mat10x8,1:10,1:8); put ColSum1=; put RowSum1=; put TotSum=; Stop; Run; Data _Null_; Array Mat{2,3} ( 1 2 3 2 3 6 ); ColSum1= %UtlSumOf ( Mat,1:2,1); ColSum2= %UtlSumOf ( Mat,1:2,2); ColSum3= %UtlSumOf ( Mat,1:2,3); RowSum1= %UtlSumOf ( Mat,1,1:3); RowSum2= %UtlSumOf ( Mat,2,1:3); Total=%UtlSumOf (Mat,1:2,1:3); Put ColSum1= / ColSum2= / ColSum3= // RowSum1= / RowSum2= // Total=; Run;
From: Chris Jones on 1 Apr 2010 18:15 On 1 Apr, 21:20, Dan Thompson <dt4...(a)gmail.com> wrote: > array cns (15,72) c1s1994--c1s2065 > c2s1994--c2s2065 > c3s1994--c3s2065 > c4s1994--c4s2065 > c5s1994--c5s2065 > c6s1994--c6s2065 > c7s1994--c7s2065 > c8s1994--c8s2065 > c9s1994--c9s2065 > c10s1994--c10s2065 > c11s1994--c11s2065 > c12s1994--c12s2065 > c13s1994--c13s2065 > c14s1994--c14s2065 > c15s1994--c15s2065; > array cns_sum (15) c1s_sum c2s_sum c3s_sum c4s_sum c5s_sum c6s_sum > c7s_sum c8s_sum c9s_sum c10s_sum c11s_sum c12s_sum c13s_sum c14s_sum > c15s_sum; > do i=1 to 15; > cns_sum(i)=sum(of cns(i,1-72)); > end; > > I also tried, with no luck: > > cns_sum(i)=sum(of cns(i,1)--cns(i,1)); Doable with a macro loop... %MACRO ARRAYSUMS ; data sums ; array cns (15,72) c1s1994--c1s2065 c2s1994--c2s2065 c3s1994--c3s2065 c4s1994--c4s2065 c5s1994--c5s2065 c6s1994--c6s2065 c7s1994--c7s2065 c8s1994--c8s2065 c9s1994--c9s2065 c10s1994--c10s2065 c11s1994--c11s2065 c12s1994--c12s2065 c13s1994--c13s2065 c14s1994--c14s2065 c15s1994--c15s2065; array cns_sum (15) c1s_sum c2s_sum c3s_sum c4s_sum c5s_sum c6s_sum c7s_sum c8s_sum c9s_sum c10s_sum c11s_sum c12s_sum c13s_sum c14s_sum c15s_sum; %DO I = 1 %TO 15 ; cns_sum(&I) = sum(of c&I.s:) ; %END ; run ; %MEND ; %ARRAYSUMS ;
From: Patrick on 2 Apr 2010 00:41 What you're missing is also missed by others (http://groups.google.com/ group/comp.soft-sys.sas/browse_thread/thread/26d744db6547fc4a/ 4076a823f349894b?lnk=gst&q=sum+array#4076a823f349894b) Below is a data step approach: data have; array cns {*} c1s1994-c1s2065 c2s1994-c2s2065 c3s1994-c3s2065 c4s1994-c4s2065 c5s1994-c5s2065 c6s1994-c6s2065 c7s1994-c7s2065 c8s1994-c8s2065 c9s1994-c9s2065 c10s1994-c10s2065 c11s1994-c11s2065 c12s1994-c12s2065 c13s1994-c13s2065 c14s1994-c14s2065 c15s1994-c15s2065; do i=1 to dim(cns); cns(i)=i; end; drop i; run; data want; set have; array cns {15,72} c1s1994-c1s2065 c2s1994-c2s2065 c3s1994-c3s2065 c4s1994-c4s2065 c5s1994-c5s2065 c6s1994-c6s2065 c7s1994-c7s2065 c8s1994-c8s2065 c9s1994-c9s2065 c10s1994-c10s2065 c11s1994-c11s2065 c12s1994-c12s2065 c13s1994-c13s2065 c14s1994-c14s2065 c15s1994-c15s2065; array cns_sum (15) c1s_sum c2s_sum c3s_sum c4s_sum c5s_sum c6s_sum c7s_sum c8s_sum c9s_sum c10s_sum c11s_sum c12s_sum c13s_sum c14s_sum c15s_sum; do i=1 to dim(cns,1); do j=1 to dim(cns,2); cns_sum(i)=sum(cns_sum(i),cns(i,j)); end; put cns_sum(i)=; end; drop i j; run; Be careful when using double dash for referencing a variable list. Double dash doesn't pick the beginning and end of a list according to alphabetical order of variable names but uses the order of how variables are stored in the dataset. See below what that means (run the code): data have; var1='var1'; x='x'; var3='var3'; var2='var2'; run; data _null_; set have; put 'Array elements list with double dash'; array VarsDblDash {*} var1--var3; do i=1 to dim(VarsDblDash); put VarsDblDash(i)=; end; put / 'Array elements list with single dash'; array VarsSglDash {*} var1-var3; do i=1 to dim(VarsSglDash); put VarsSglDash(i)=; end; run; HTH Patrick
|
Pages: 1 Prev: how to export only few variables using proc export Next: The problem with sorting MONYY7. data |