SAS Enterprise Guide

Desktop productivity for business analysts and programmers
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-white.png

    Special offer for SAS Communities members

    Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

     

    View the full agenda.

    Register now!

    Creating Custom Steps in SAS Studio

    Check out this tutorial series to learn how to build your own steps in SAS Studio.

    Find more tutorials on the SAS Users YouTube channel.

    SAS Training: Just a Click Away

     Ready to level-up your skills? Choose your own adventure.

    Browse our catalog!

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