Search code examples
stringsasdo-whiledo-loops

How to increment string in variable using loop in SAS


I am a beginner user in SAS. I have a table Dose_turn with columns Month for month and Doses for dose of different products. I want to set value of doses of specific months to 0 using a loop wherever its the specific product P13. If I want to change the value of dose of just one month, the code is simple and is as follows:

Data Dose_Trn_2;
Set Dose_Trn;
if Prd_Name = 'P13' and Month= 'Mnth_1' then Doses=0;
run;

Now if i want to change for example for 4 months, can I achieve the same using a loop where month automatically takes in the values 'Mnth_1', 'Mnth_2', 'Mnth_3', 'Mnth_4' based on some condition/increment in the loops like do while or do until loops. I tried using %let and & inside a do loop as shown below:

Data Dose_Trn_m12;
Set Dose_Trn;
do i=1 to 4 by 1;
   %let initial = i;
   if Prd_Name = 'PCV13' and Month= "Mnth_&initial" then Doses=0;
end;
run;

However the above code did not change the value of doses to 0 for Mnth_1, Mnth_3, Mnth_3 and Mnth_4 as I expected. %let and & worked when not used inside a do loop but with the do loop its not working as the doses value didnt change. The reason why I want to implement loop is the months for which doses need to be changed can vary each time based on some prior conditions of data of that month. Can someone suggest a workaround for this problem?


Solution

  • You can do this in a single if statement. SAS is already looping for us by reading each row one-by-one.

    We know that the month number is the number part of Mnth_X separated by _. We can use the scan function to pull this value, which we can then compare. So, the overall logic we want is:

    If the Prd_Name is P13 and the month number is between 1 and 4, make doses = 0

    Which looks like this:

    data want;
        set dose_trn;
      
        if(prd_name = 'P13' AND 1 <= scan(Month, -1, '_') <= 4)
            then doses = 0;
    run;
    

    The neat thing about SAS is that it is able to identify that we've pulled out a number and will do the conversion of a string to a number for us.

    If you want to select specific months, you can do this:

    data want;
        set dose_trn;
      
        if(prd_name = 'P13' AND scan(Month, -1, '_') IN(1, 3, 4) )
            then doses = 0;
    run;
    

    Again, SAS converts the string to a number for us which you can see in the log.