SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Sami1234
Fluorite | Level 6

 

Wondering if someone can help me, please?

I would like to create another variable depending on if the variable exists in the dataset.

If the variable does not exists in the dataset then no need to create the variable.

At the moment, it's creating a blank variable for M0 and STD0 (as they don't exist) and throwing a warning in the log for the uninitialized variables.

Also, would it be possible to create a loop or an array to do the checks and create (diff0-diff9) variables for up to 10 variables (m0-m9) depending on if the correspondence variables exist?

 

 

Thank you!

 

data testb;

set testa;

if _n_=1 then do;

dsid=open('testa');

varexistm0 = varnum(dsid,'M0') ;

varexistm1 = varnum(dsid,'M1') ;

varexistm2 = varnum(dsid,'M2') ;

varexists0 = varnum(dsid,'STD0') ;

varexists1 = varnum(dsid,'STD1') ;

varexists2 = varnum(dsid,'STD2') ;

       

 

 

 

rc=close(dsid);

end;

drop rc dsid;

 

if varexistm0 > 0 and  varexists0 >0 then do;

diff0= (m10 - m0) / sqrt((std10**2 + std0**2) / 2);      

 

end;

 

if varexistm1 > 0 and  varexists1 >0 then do; then do;

diff1= (m10 - m1) / sqrt((std10**2 + std1**2) / 2);

 end;      

if varexistm2 > 0 and  varexists2 >0 then do;

diff2= (m10 - m2) / sqrt((std10**2 + std2**2) / 2);

 

 

end;

 

run;

 

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
s_lassen
Meteorite | Level 14

The variables are created even if you do not write to them in your datastep.

 

I would split the code in two datasteps, and use the first datastep to generate code for the second:

filename tempsas temp;

data _null_;
dsid=open('testa');
varexistm0 = varnum(dsid,'M0') ;
varexistm1 = varnum(dsid,'M1') ;
varexistm2 = varnum(dsid,'M2') ;
varexists0 = varnum(dsid,'STD0') ;
varexists1 = varnum(dsid,'STD1') ;
varexists2 = varnum(dsid,'STD2') ;
rc=close(dsid);
end;
 
file tempsas;
if varexistm0 > 0 and  varexists0 >0 then 
  put 'diff0= (m10 - m0) / sqrt((std10**2 + std0**2) / 2);';      
 
if varexistm1 > 0 and  varexists1 >0 then 
  put 'diff1= (m10 - m1) / sqrt((std10**2 + std1**2) / 2);';

if varexistm2 > 0 and  varexists2 >0 then 
put 'diff2= (m10 - m2) / sqrt((std10**2 + std2**2) / 2);';
run;


data testb;
  set testa;
  %include tempsas/source2;
run;
  

View solution in original post

3 REPLIES 3
Kurt_Bremser
Super User

Pull the metadata from dictionary.columns, and then use da data _null_ step to dynamically generate the code:

(I used a simple subtraction as the mathematical operation to be performed)

data have;
input id $ m0 m1 std0 std1;
datalines;
x 1 2 3 5
;
run;

proc sql noprint;
create table variables as
select name, substr(name,length(name)) as seq
from dictionary.columns
where libname = 'WORK' and memname = 'HAVE' and anydigit(calculated seq);
select name into :vars separated by ' ' from variables order by seq, name;
quit;

data _null_;
call execute("data want; set have;");
do i = 1 to countw("&vars.") by 2;
  put _all_;
  targetvar = "diff" !! substr(scan("&vars.",i),length(scan("&vars.",i)));
  call execute(targetvar !! '=' !! scan("&vars.",i+1) !! '-' !! scan("&vars.",i) !! ';');
end;
call execute("run;");
run;

proc print data=want noobs;
run;

Result:

id    m0    m1    std0    std1    diff0    diff1

x      1     2      3       5       2        3  
s_lassen
Meteorite | Level 14

The variables are created even if you do not write to them in your datastep.

 

I would split the code in two datasteps, and use the first datastep to generate code for the second:

filename tempsas temp;

data _null_;
dsid=open('testa');
varexistm0 = varnum(dsid,'M0') ;
varexistm1 = varnum(dsid,'M1') ;
varexistm2 = varnum(dsid,'M2') ;
varexists0 = varnum(dsid,'STD0') ;
varexists1 = varnum(dsid,'STD1') ;
varexists2 = varnum(dsid,'STD2') ;
rc=close(dsid);
end;
 
file tempsas;
if varexistm0 > 0 and  varexists0 >0 then 
  put 'diff0= (m10 - m0) / sqrt((std10**2 + std0**2) / 2);';      
 
if varexistm1 > 0 and  varexists1 >0 then 
  put 'diff1= (m10 - m1) / sqrt((std10**2 + std1**2) / 2);';

if varexistm2 > 0 and  varexists2 >0 then 
put 'diff2= (m10 - m2) / sqrt((std10**2 + std2**2) / 2);';
run;


data testb;
  set testa;
  %include tempsas/source2;
run;
  
Sami1234
Fluorite | Level 6

Thank you so much, that works absolutely fine without any warnings.

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

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
  • 1663 views
  • 0 likes
  • 3 in conversation