BookmarkSubscribeRSS Feed
RobF
Quartz | Level 8

l

I've written a routine that calculates a penalized logistic regression by reading my dataset into a two dimensional array, then iteratively looping through the dataset array by columns and rows and updating the values in the regression parameter array.

I'm having a surprisingly difficult time successfully writing a statement that gracefully exits the "j=0 to &numvars" do loop if the current value of p_ equals 0 (see >>> arrows indicating the program line below).

Basically, if the current value of p_ = 0, then there's no need to update the value of p_ and the program should continue to the (j+1)th parameter in the do loop. I don't want to exit the "j=0 to &numvars" do loop - just skip to the next value of j in the sequence.

I've tried leave, continue, and goto statements, but no luck.

Running the code below with the goto statement, I receive the following error:

145             end; * End lambda values loop ;

146       

147             end; * End alpha values loop ;

                ___

                161

ERROR 161-185: No matching DO/SELECT statement.

148       

149       

150       

151        run;

Any ideas what I'm doing wrong & how I ought to proceed? Thanks in advance!

**********************************************************************

*    Logistic regression coordinate descent code for elastic net      *

**********************************************************************;

%let nobs=442;

%let numvars=10;

%let numvars2=11;

%let numiter=1000;

%let lambda_list=.1;

%let alpha_list=1;

data coord_descent_output (keep=alpha lambda p_0-p_&numvars2.);

     array xx[0:&numvars.] x0-x&numvars.

     array x_[&nobs.,0:&numvars.] _temporary_;

     array y_[&nobs] _temporary_;

*** Load data into two dimensional array ***;

     do _n_ = 1 to &nobs.;

             set diabetes_stnd_array2 nobs=nobs;

             do j=0 to &numvars.;

           x_[_n_,j] = xx;

           y_[_n_] = y_gt140;

             end;

     end;

*** Coordinate descent routine ***;

     do alpha=&alpha_list; * Start alpha values loop ;

     do lambda=&lambda_list; * Start lambda values loop ;

   gamma=alpha*lambda;

     array p_[0:&numvars.] (&numvars2.*1); * Assign initial parameter values ;

     do i=1 to &numiter; * Start iteration loop ;

           do j=0 to &numvars; * Start data column loop ;

  >>>       if p_=0 then goto endloop; * Bypass calculations and proceed to p_[j+1] if p_=0 ;

          z = 0;

          sum_wtx_sq = 0;

                    do _nn_ = 1 to &nobs; * Start data record loop ;

             yhat = p_[0];

                          do k=1 to &numvars;

                  yhat = sum(yhat, p_*x_[_nn_,k]);

                          end;

             proby = 1/(1 + exp(-yhat));

                         if proby <= .00001 then do;

                  proby = 0;

                  weight = .00001;

                          end;

                          else if proby >= .99999 then do;

                  proby = 1;

                  weight = .00001;

                         end;

                         else weight = proby*(1 - proby);

            z = sum(z, (x_[_nn_,j]*(y_[_nn_] - proby) + weight*p_*(x_[_nn_,j])**2));

            sum_wtx_sq = sum(sum_wtx_sq, weight*(x_[_nn_,j])**2);

                end; * End data record loop ;

                if j=0 then do;

           p_ = z/sum_wtx_sq;

                end;

                else if j>0 then do;

                     if (z/&nobs > 0 and gamma < abs(z/&nobs)) then p_ = (z/&nobs - gamma)/(sum_wtx_sq/&nobs + lambda - gamma);

                     else if (z/&nobs < 0 and gamma < abs(z/&nobs)) then p_ = (z/&nobs + gamma)/(sum_wtx_sq/&nobs + lambda - gamma);

                     else if gamma >= abs(z/&nobs) then p_ = 0;

                end;

>>>     endloop: end; * End p_=0 bypass loop ;

          end; * End data column loop ;

     end; * End iteration loop ;

     output coord_descent_output;

     put "p_

  • ="
  • p_
  • ;
  •      end; * End lambda values loop ;

         end; * End alpha values loop ;

    run;

    3 REPLIES 3
    Reeza
    Super User

    I didn't read all of your code but could you reverse the condition?

    if p_ ne 0 then do;

    *rest of code


    end;

    ballardw
    Super User

    Depending on desired behavior you may want one of:

    if p_=0 then leave;

    or

    if p_=0 then continue;

    Leave would stop the iteration of the J loop, Continue would move to the next iteration (J+1)

    RobF
    Quartz | Level 8

    Thanks guys - unfortunately neither of these suggestions is working. The program runs without error, however the output parameter values are incorrect (compared to running the code without any p_=0 bypass options at all).

    I have a feeling there's a logic error rather than a syntax error here, alas.

    sas-innovate-2024.png

    Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

    Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

     

    Register now!

    SAS Enterprise Guide vs. SAS Studio

    What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

    Find more tutorials on the SAS Users YouTube channel.

    Click image to register for webinarClick image to register for webinar

    Classroom Training Available!

    Select SAS Training centers are offering in-person courses. View upcoming courses for:

    View all other training opportunities.

    Discussion stats
    • 3 replies
    • 5992 views
    • 0 likes
    • 3 in conversation