BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
chinna0369
Pyrite | Level 9

Hi,

 

I am trying to output records for each record with available avisit by using do loop as below. But I am getting below erro, please let me know what I am missing.

 

%let var1=1;
%let var2=2;
%let var3=3;
%let var4=4;
%let var5=5;
%let var6=6;

%let num=6;

data adsl_vis;
	set adsl(keep=usubjid subjid);
	do i=1 to #
	avisitn=&&var&i; 
	output;
	end;
run;

chinna0369_0-1720814804182.png

Thanks,

Chinna

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

Macro variables resolve before the data step starts to execute.

So please describe what you want in a bit more detail. This macro approach is cumbersome and placing many values into macro variables is quite often not a good idea in general.

 

You are using &i, which expects a macro variable named I to exist. The macro processor does not see data step variable values. If you must in a data step the function is SYMGET. (Please don't use data set's not defined )

data adsl_vis;
/*	set adsl(keep=usubjid subjid);*/
	do i=1 to #
	   avisitn=symget('var'||left(i)); 
	output;
	end;
run;

However than would create 6 output records for each one read, is that the desire?

 

However if the purpose of this is to create a sequence number then perhaps:

data adsl_vis;
   set adsl(keep=usubjid subjid);
   avisitn=_n_;
run;

 

 

View solution in original post

6 REPLIES 6
ballardw
Super User

Macro variables resolve before the data step starts to execute.

So please describe what you want in a bit more detail. This macro approach is cumbersome and placing many values into macro variables is quite often not a good idea in general.

 

You are using &i, which expects a macro variable named I to exist. The macro processor does not see data step variable values. If you must in a data step the function is SYMGET. (Please don't use data set's not defined )

data adsl_vis;
/*	set adsl(keep=usubjid subjid);*/
	do i=1 to #
	   avisitn=symget('var'||left(i)); 
	output;
	end;
run;

However than would create 6 output records for each one read, is that the desire?

 

However if the purpose of this is to create a sequence number then perhaps:

data adsl_vis;
   set adsl(keep=usubjid subjid);
   avisitn=_n_;
run;

 

 

chinna0369
Pyrite | Level 9
In this example I have 6 visitnum I want to create a dataset with all the records in ADSL with all those 6 visits.
chinna0369
Pyrite | Level 9
For example, I have 10 records in adsl with unique id. I want my final data 6*10 60 records should be there with each record and each visit.
chinna0369
Pyrite | Level 9
Yes, it is working but getting following note
1983 %put &var1 &var3 &var4 &var5 &var6 &var2 #
1200 1320 1360 1400 1520 1240 6
1984
1985 %let var1=1;
1986 %let var2=2;
1987 %let var3=3;
1988 %let var4=4;
1989 %let var5=5;
1990 %let var6=6;
1991
1992 %let num=6;
1993
1994 data adsl_vis;
1995 set adsl(keep=usubjid subjid);
1996 do i=1 to &num.;
1997 avisitn=symget('var'||left(i));
1998 output;
1999 end;
2000 run;

NOTE: Numeric values have been converted to character values at the places given by:
(Line):(Column).
1997:32
NOTE: There were 351 observations read from the data set WORK.ADSL.
NOTE: The data set WORK.ADSL_VIS has 2106 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds


chinna0369
Pyrite | Level 9
By the way the variable which we are creating should be numeric AVISITN.
ballardw
Super User

@chinna0369 wrote:
By the way the variable which we are creating should be numeric AVISITN.
avisitn=input(symget('var'||left(i)),8.);

Basic use of INPUT to guarantee numeric result (and a hint why macro variables may not be a good approach)

 

If you want to add the same set of avisitn values to each record in the data set:

data avisitn_data;
   input avisitn;
datalines;
1
2
3
4
5
6
;

Proc sql create table adsl_vis as
   select a.usubjid,a.subjid
          ,b.avisitn
   from adsl as a,avisitn_data as b
   ;
quit;

The Proc SQL JOINS two data sets in a Cartesian Join, meaning every observation in one set is combined with every observation in a different data set.

IF however the data set Adsl already has values of Avisitn and you want to select only matching ones:

Proc sql create table want as
   select a.*
   from adsl as a
        right join
        avisitn_data a b
        on a.avisitn=b.avisitn
   ;
quit;

Note that in neither case do you have to create multiple macro variables, attempt to use the sometimes flaky macro indirect reference or even count the number of values involved. Just place the list into the data set and Proc Sql will do the work.

 

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 6 replies
  • 2309 views
  • 0 likes
  • 2 in conversation