Statistical programming, matrix languages, and more

How do I use a by or class statement in proc iml?

Accepted Solution Solved
Reply
Super Contributor
Posts: 303
Accepted Solution

How do I use a by or class statement in proc iml?

Hello,I wish to perform this procedure by replicate. I have a by replicate but it gave me the error message below. Any help?

proc iml;

     use Complete_&p;

    read all var _all_ into DM;   

      close;

    frequency =DM[,7]; y =DM[,6]; obs=DM[,5]; Censored= DM[,4]; time = DM[,3];  x =DM[,2];replicate=DM[,1];

      use GIB_&p;

    read all var _all_ into Col;

by replicate;

 

timeS=time;

locC=loc(censored=1); matrix=J(1,8,2.5);

do im=1 to 1;

do j= 1 to frequency[1];

seed=-1;

   A=RANUNI(-1);

     i=max(loc(Col[,j]-A>0));

if i<nrow(time) then   /** do nothing if the last is censored, that is         censored=1*****/

      do;

timeS[locC] = time+ (time[i+1]-time)*((Col[i,j]-A)/(Col[i,j]+col[i+1,j]));

      end;

end;

sim=repeat(im,nrow(time),1);

temp=obs||censored||time||Y||timeS||X||sim||replicate;

Matrix=matrix//temp;

end; matrix=matrix[2:nrow(matrix),];

create impute_t_&p var{obs censored time Y timeS  X sim replicate};

      append from matrix;

quit;

ods trace on/listing;

NOTE: IML Ready

NOTE: Closing WORK.COMPLETE_1

NOTE: Line generated by the invoked macro "SURV".

30         by replicate;

           --

           180

ERROR 180-322: Statement is not valid or it is used out of proper order.

NOTE: Exiting IML.

NOTE: The data set WORK.IMPUTE_T_1 has 500 observations and 8 variables.

NOTE: The SAS System stopped processing this step because of errors.

NOTE: PROCEDURE IML used (Total process time):

      real time           0.98 seconds

      cpu time            0.04 seconds


Accepted Solutions
Solution
‎11-02-2013 10:04 AM
Super Contributor
Posts: 303

Re: Hoy do I use aby or class statement in proc iml?

Hello Rick,

I have modified my code as you said. This is the code, but it does not creat GIB. I do not know the dimension so I do not know how to set a default matrix;

proc iml;

use KMM_&p;

read all var{time censored  survival1 frequency y replicate } into DM;

/*read the 3 variables into matrix*/ /*have to print within DM*/

close;                                                                                     /*close the link between the dataset and IML*/

  replicate=DM[,6]; y=DM[,5];frequency =DM[,4]; survival1 =DM[,3]; Censored= DM[,2]; time = DM[,1];   /*Survivalival is second column*/  /*time is first column*/

n = nrow(DM);

/*number of rows in the dataset = obs*/ /*THE N DOESNT NEED TO BE FIXED*/

                     /*Segment equals the number of consecutive patterns*/ /*J creates a matrix in IML , it creates a 100x1 matrix of 1s, the 3rd 1 is the value in matrix*/

segment = J(nrow(DM),1,1); *print segment;

do k = 1 to ncol(u);

byIdx = loc(replicate=u); /* the UNIQUE-LOC trick */

byGroup = DM[idx,];

y=byGroup[,5];freqency =byGroup[,4]; survival1 =byGroup[,3]; Censored= byGroupDM[,2]; time = timeDM[,1];

do i = 2 to nrow(DM);

if ((Censored=1)=(Censored[i-1]=1)) then segment=segment[i-1];  /**/        /* coming up with unique segments for censored*****/;

else if ((Censored=1)=1-(Censored[i-1]=1)) then segment=segment[i-1]+1;

                     *print time survival1 censored frequency segment;                                  

*print segment;

end;

    SurvivalM=J(nrow(survival1),1,1);

      do i = 1 to n;

         if censored=1 then SurvivalM=survival1; else if censored=0 then SurvivalM=survival1;  /*****Create a 1 by N -matrix of Survival ****/;

            

end;

   

      *print SurvivalM;

    InverseC=J(nrow(survival1),1,1);

   do i = 1 to n;

if censored=1 then InverseC=1/survival1; else if censored=0 then InverseC=0;  /*****survivalC is the imputed censored survival and set the real Survivalval to 1**/;

         end;

do i = 1 to ncol(frequency);

call symputx("j", i);

   m = num(symget("j"));

   m=1*m; print m;  %let mm=m;

end;

t=InverseC[(loc(InverseC^=0))]; print t;

tt=t(t); print tt;

Big=SurvivalM*(tt);

end;

create GIB_&p from BIG[colname={COL1}];                                 

append from BIG;

quit;

LOCK FILE

NOTE: IML Ready

NOTE: Closing WORK.KMM_1

ERROR: Matrix Big has not been set to a value.

statement : CREATE at line 913 column 93

ERROR: No data set is currently open for output.

statement : APPEND at line 913 column 133

NOTE: Exiting IML.

NOTE: The SAS System stopped processing this step because of errors.

NOTE: PROCEDURE IML used (Total process time):

      real time           0.00 seconds

      cpu time            0.01 seconds

View solution in original post


All Replies
Trusted Advisor
Posts: 1,770

Re: Hoy do I use aby or class statement in proc iml?

There is no BY statement or CLASS statement for PROC IML

You have to write a loop in IML code, and then loop over all possible values of the BY variable. All possible values of the BY variable can be determined by using the IML function UNIQUE or UNIQUEBY

SAS Super FREQ
Posts: 3,615

Re: Hoy do I use aby or class statement in proc iml?

Super Contributor
Posts: 303

Re: Hoy do I use aby or class statement in proc iml?

I used the blog,this is my code,runs in my simulations but I do not know if it is doing the right. I just want it to run like a by statement;  I bold it. Does what is withing the bold do statement works by a by statement?  I do not think correct because the matrix GIB is supposed to be of varying dimension but that snot what I got or may be the way I created my matrix is wrong.

proc iml;

use KMM_&p;

read all var{time censored  survival1 frequency y replicate } into DM;

/*read the 3 variables into matrix*/ /*have to print within DM*/

close;                                                                                     /*close the link between the dataset and IML*/

  replicate=DM[,6]; y=DM[,5];frequency =DM[,4]; survival1 =DM[,3]; Censored= DM[,2]; time = DM[,1];   /*Survivalival is second column*/  /*time is first column*/

n = nrow(DM);

/*number of rows in the dataset = obs*/ /*THE N DOESNT NEED TO BE FIXED*/

                     /*Segment equals the number of consecutive patterns*/ /*J creates a matrix in IML , it creates a 20x1 matrix of 1s, the 3rd 1 is the value in matrix*/

segment = J(nrow(DM),1,1); *print segment;

u = unique(replicate);

s = j(1, ncol(u));

do i=1  to ncol(u);

do i = 2 to nrow(DM);

if ((Censored=1)=(Censored[i-1]=1)) then segment=segment[i-1];  /**/        /* coming up with unique segments for censored*****/;

else if ((Censored=1)=1-(Censored[i-1]=1)) then segment=segment[i-1]+1;

                     *print time survival1 censored frequency segment;                                 

*print segment;

end;

    SurvivalM=J(nrow(survival1),1,1);

      do i = 1 to n;

         if censored=1 then SurvivalM=survival1; else if censored=0 then SurvivalM=survival1;  /*****Create a 1 by N -matrix of Survival ****/;

           

end;

  

      *print SurvivalM;

    InverseC=J(nrow(survival1),1,1);

   do i = 1 to n;

if censored=1 then InverseC=1/survival1; else if censored=0 then InverseC=0;  /*****survivalC is the imputed censored survival and set the real Survivalval to 1**/;

         end;

*print InverseC;

m=frequency[1]; m=1*m; print m;  %let mm=m;

t=InverseC[(loc(InverseC^=0))]; print t;

tt=t(t); print tt;

Big=SurvivalM*(tt);

end;

create GIB_&p from BIG[colname={COL1}];                                

append from BIG;

quit;

SAS Super FREQ
Posts: 3,615

Re: Hoy do I use aby or class statement in proc iml?

Since you marked this question "Answered," I almost didn't look at your program.

Your program does not look to be correct. I recommend that you re-study the code from the blogs so that you understand why the statements give the functionality of BY groups. There are several problems with your program.

1) You can't use 'i' for nested loops. Change the index variable of the outer loop that currently reads DO i=1 to ncol(u)

2) I don't see any LOC statements that extract the relevant rows of the data. You need to extract the observations for each BY group like this

do k = 1 to ncol(u);

   byIdx = loc(replicate=u); /* the UNIQUE-LOC trick */

   byGroup = DM[idx,];          /* extract BY group */

   y=byGroup[,5];freqency =byGroup[,4]; survival1 =byGroup[,3];etc

   /* do analysis for these rows */

end;

SAS Super FREQ
Posts: 3,615

Re: Hoy do I use aby or class statement in proc iml?

By the way, you don't appear to be using the &mm macro variable, but you should be aware that your %LET statement isn't doing what you think it is doing. The value of &mm is always the character 'm'. For an explanation, see Macros and loops in the SAS/IML language - The DO Loop

Solution
‎11-02-2013 10:04 AM
Super Contributor
Posts: 303

Re: Hoy do I use aby or class statement in proc iml?

Hello Rick,

I have modified my code as you said. This is the code, but it does not creat GIB. I do not know the dimension so I do not know how to set a default matrix;

proc iml;

use KMM_&p;

read all var{time censored  survival1 frequency y replicate } into DM;

/*read the 3 variables into matrix*/ /*have to print within DM*/

close;                                                                                     /*close the link between the dataset and IML*/

  replicate=DM[,6]; y=DM[,5];frequency =DM[,4]; survival1 =DM[,3]; Censored= DM[,2]; time = DM[,1];   /*Survivalival is second column*/  /*time is first column*/

n = nrow(DM);

/*number of rows in the dataset = obs*/ /*THE N DOESNT NEED TO BE FIXED*/

                     /*Segment equals the number of consecutive patterns*/ /*J creates a matrix in IML , it creates a 100x1 matrix of 1s, the 3rd 1 is the value in matrix*/

segment = J(nrow(DM),1,1); *print segment;

do k = 1 to ncol(u);

byIdx = loc(replicate=u); /* the UNIQUE-LOC trick */

byGroup = DM[idx,];

y=byGroup[,5];freqency =byGroup[,4]; survival1 =byGroup[,3]; Censored= byGroupDM[,2]; time = timeDM[,1];

do i = 2 to nrow(DM);

if ((Censored=1)=(Censored[i-1]=1)) then segment=segment[i-1];  /**/        /* coming up with unique segments for censored*****/;

else if ((Censored=1)=1-(Censored[i-1]=1)) then segment=segment[i-1]+1;

                     *print time survival1 censored frequency segment;                                  

*print segment;

end;

    SurvivalM=J(nrow(survival1),1,1);

      do i = 1 to n;

         if censored=1 then SurvivalM=survival1; else if censored=0 then SurvivalM=survival1;  /*****Create a 1 by N -matrix of Survival ****/;

            

end;

   

      *print SurvivalM;

    InverseC=J(nrow(survival1),1,1);

   do i = 1 to n;

if censored=1 then InverseC=1/survival1; else if censored=0 then InverseC=0;  /*****survivalC is the imputed censored survival and set the real Survivalval to 1**/;

         end;

do i = 1 to ncol(frequency);

call symputx("j", i);

   m = num(symget("j"));

   m=1*m; print m;  %let mm=m;

end;

t=InverseC[(loc(InverseC^=0))]; print t;

tt=t(t); print tt;

Big=SurvivalM*(tt);

end;

create GIB_&p from BIG[colname={COL1}];                                 

append from BIG;

quit;

LOCK FILE

NOTE: IML Ready

NOTE: Closing WORK.KMM_1

ERROR: Matrix Big has not been set to a value.

statement : CREATE at line 913 column 93

ERROR: No data set is currently open for output.

statement : APPEND at line 913 column 133

NOTE: Exiting IML.

NOTE: The SAS System stopped processing this step because of errors.

NOTE: PROCEDURE IML used (Total process time):

      real time           0.00 seconds

      cpu time            0.01 seconds

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 481 views
  • 6 likes
  • 3 in conversation