0

I am trying to save a vector named ez product of some matrix calculations based on a group variable named ID_bloque. For each ID_bloque value my code computes a vector called ez and append it in a matrix with the same name. However, if zk is a missing data vector (which is not a mistake) the code stops and make no other computations, which is a problem for other groups since no calculations are made for them. Is there any way to force append clause to keep this data and those resulting for the other groups? Thank you so much

proc iml;
/*Maximo= maximum ID_bloque value*/
do i=1 to %EVAL(&MAXIMO);
     use T6; /*Dataset*/
     /*Variables*/
     read all var{E1S1 E1S2 E2S1 E2S2 E3S1 E3S2 E4S1 E4S2} 
                                     into XK where (ID_bloque=i) ;
     read all var{FEX_P} into dk where (ID_bloque=i) ;
     read all var{VK} into vk where (ID_bloque=i) ;
     read all var{z} into zk where (ID_bloque=i) ;
     /* Matrix computations */
     MAT=J(NCOL(XK),NCOL(XK),0);
     do j=1 to Nrow(XK);
          MAT= MAT + dk[j]*vk[j]*((XK[j,]`)*XK[j,]);
     end;
     /* ez values depending on missing information in zk*/
     if all(zk)=. then do;
          ez=zk;
     end;
     else do;
          Brz=(Ginv(MAT))*((XK`)*(dk#vk#zk));
          ez=zk-XK*Brz;
     end;
     /* Vectors appending (error source) */
     if i=1 then do;
          create ez var{ez}; APPEND;
     end;else do; APPEND var{ez} ;end;
end;
close ez;
quit;

1 Answers1

0

To check whether a vector is all missing, you should use if all(zk = .) then...

The best way to handle appending to a data set within a loop is to open the data set BEFORE the loop, append within the loop, and then close after the loop. SAS needs to know what data types and lengths will be written, so I usually use fake data (such as missing values) when I open the data set just to provide the variable types.

Lastly, the MAT computation you are doing is a matrix multiplication, so you can simplify that computation:

proc iml;
/*Maximo= maximum ID_bloque value*/
ez = .;             /* tell IML that ez is a numeric vector */
create ez var {ez}; /* open the data set */

do i=1 to %EVAL(&MAXIMO);
     use T6; /*Dataset*/
     /*Variables*/
     read all var{E1S1 E1S2 E2S1 E2S2 E3S1 E3S2 E4S1 E4S2} 
                                     into XK where (ID_bloque=i) ;
     read all var{FEX_P} into dk where (ID_bloque=i) ;
     read all var{VK} into vk where (ID_bloque=i) ;
     read all var{z} into zk where (ID_bloque=i) ;
     /* Matrix computations */
     /*
     MAT=J(NCOL(XK),NCOL(XK),0);
     do j=1 to Nrow(XK);
          MAT= MAT + dk[j]*vk[j]*((XK[j,]`)*XK[j,]);
     end;
     */
     MAT = (dk#vk#XK)` * XK;
     /* ez values depending on missing information in zk*/
     if all(zk=.) then do;
          ez=repeat(1, Nrow(XK));
     end;
     else do;
          Brz=(Ginv(MAT))*((XK`)*(dk#vk#zk));
          ez=zk-XK*Brz;
     end;
     /* Vectors appending (error source) */
     append;
end;
close ez;
quit;
Rick
  • 1,210
  • 6
  • 11
  • Thanks for your answer. Do you know if it is possible to append missing-value vector to ``ez``? – Jorge Mendoza Ruiz Apr 13 '19 at 17:58
  • Yes. The APPEND statement will append any values, including missing. I suspect your previous problem was with the ALL statement. – Rick Apr 14 '19 at 22:43