DATA Step, Macro, Functions and more

Do loop assignments

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 123
Accepted Solution

Do loop assignments

Hello SAS users,

 

Need  help with tuning this query.

Read the diag codes , if decimals in the data, replace the dots  (5.1 should become 5) if no decimal present retain the data as it is. I am not getting any values in put statements.

 

 

%macro test1;
data test;

diag_1 = 5.1;
diag_2 = 4;
diag_3 = 4.7;
run;


%do i = 1 %to 3;
   %if %index(diag_&i,".") > 0
    %then
      diag_&i = tranwrd(diag_&i,".","");

    %else

    diag_&i;
      %put &diag_&i;
 %END;

 
 %mend;


Accepted Solutions
Solution
‎03-28-2018 11:52 PM
Super User
Super User
Posts: 7,844

Re: Do loop assignments

[ Edited ]

@SASAna wrote:
Thanks for the answer. what is the approach do i have to take if the %index is always zero.

I tried to work with data set and i am getting the original values for 1,2,3 diag's.
data fix;
set test;
%do i = 1 %to 3;
%if %index(&(diag_&i.),".") > 0
%then
diag_&i. = tranwrd(&(diag_&i.),".","");
%put &=diag_&i.;
%end;
run


;


I thought you had the data in dataset variables? 

If you want to operate on a series of variables you should learn how to use the ARRAY statement. 

Also if you want to use string functions like INDEX() or TRANWRD() make sure that you have defined your variables as character variables and not numeric variables.

 

Let's make a sample dataset that has three character variables named DIAG1 to DIAG3 

data test;
  length diag1-diag3 $10 ;
  input diag1-diag3;
cards;
5.1 4 4.7
;

And write a program to remove the periods from the values of those variables.

Here is how you could do it with an ARRAY statement and a DO loop.

data want ;
  set test;
  array dx diag1-diag3;
  do i=1 to dim(dx);
     dx(i)=compress(dx(i),'.');
  end;
run;

If you want to use macro code to generate a series of statements then make sure the statements you are generating are valid SAS statements.  For example instead of using an ARRAY you could just type out a separate statement for each of the variables.

data want;
  set test;
  diag1= compress(diag1,'.');
  diag2= compress(diag2,'.');
  diag3= compress(diag3,'.');
run;

Now that you have some code that can run you could try to construct a macro that will generate the repetitive statements for you.

%macro test;
data want ;
  set test;
%do i=1 %to 3;
  diag&i = compress(diag&i,'.');
%end;
run;
%mend ;
%test;

 

View solution in original post


All Replies
Super User
Super User
Posts: 7,844

Re: Do loop assignments

[ Edited ]

First figure out how to write the code using SAS.  Then you if there is some parts that need to change systematically  or there is repetitive code that you would like to generate you can look into trying to use macro coding.

 

Right now your %IF condition will always be false because the %INDEX() function will always return zero.  There are no periods in either the string diag_ or the value of the macro variable I since the macro variable will only every have integer values.  Plus you are trying to use the macro to generate assignment statements that can only work in a data step, but you did not call the macro inside of a data step so any assignment statement it generates will just cause syntax errors for SAS.

 

 

 

Frequent Contributor
Posts: 123

Re: Do loop assignments

Thanks for the answer. what is the approach do i have to take if the %index is always zero.

I tried to work with data set and i am getting the original values for 1,2,3 diag's.

data fix;
set test;
%do i = 1 %to 3;
%if %index(&(diag_&i.),".") > 0
%then
diag_&i. = tranwrd(&(diag_&i.),".","");
%put &=diag_&i.;
%end;
run;
Solution
‎03-28-2018 11:52 PM
Super User
Super User
Posts: 7,844

Re: Do loop assignments

[ Edited ]

@SASAna wrote:
Thanks for the answer. what is the approach do i have to take if the %index is always zero.

I tried to work with data set and i am getting the original values for 1,2,3 diag's.
data fix;
set test;
%do i = 1 %to 3;
%if %index(&(diag_&i.),".") > 0
%then
diag_&i. = tranwrd(&(diag_&i.),".","");
%put &=diag_&i.;
%end;
run


;


I thought you had the data in dataset variables? 

If you want to operate on a series of variables you should learn how to use the ARRAY statement. 

Also if you want to use string functions like INDEX() or TRANWRD() make sure that you have defined your variables as character variables and not numeric variables.

 

Let's make a sample dataset that has three character variables named DIAG1 to DIAG3 

data test;
  length diag1-diag3 $10 ;
  input diag1-diag3;
cards;
5.1 4 4.7
;

And write a program to remove the periods from the values of those variables.

Here is how you could do it with an ARRAY statement and a DO loop.

data want ;
  set test;
  array dx diag1-diag3;
  do i=1 to dim(dx);
     dx(i)=compress(dx(i),'.');
  end;
run;

If you want to use macro code to generate a series of statements then make sure the statements you are generating are valid SAS statements.  For example instead of using an ARRAY you could just type out a separate statement for each of the variables.

data want;
  set test;
  diag1= compress(diag1,'.');
  diag2= compress(diag2,'.');
  diag3= compress(diag3,'.');
run;

Now that you have some code that can run you could try to construct a macro that will generate the repetitive statements for you.

%macro test;
data want ;
  set test;
%do i=1 %to 3;
  diag&i = compress(diag&i,'.');
%end;
run;
%mend ;
%test;

 

Frequent Contributor
Posts: 123

Re: Do loop assignments

Thanks Tom. I used the macro method and it worked very well.

Super User
Super User
Posts: 7,844

Re: Do loop assignments


@SASAna wrote:
Thanks Tom. I used the macro method and it worked very well.


You should wait to start using macros until after you understand how to write SAS code.

☑ This topic is solved.

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

Discussion stats
  • 5 replies
  • 131 views
  • 1 like
  • 2 in conversation