BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
SamuelKnapp
Calcite | Level 5

Hello,

I would like to replace a fixed string of charaters in the variable names of a dataset. I created the follwing example. I don't want give the number of columns, but automatically loop over all columns. However, I always get this error message:

ERROR: Required operator not found in expression: dim(cols)

Many thanks

 

/* create test data */
data test (drop= i);
	array a{*} A1-A3;
	do i=1 to dim(a);
		a{i}=i;
	end;
run;

/* with specifying the number of coluns */
%macro doit(ncols=3);
data testB;
	set test;
	%do i = 1 %to &ncols;
		rename A&i.=B&i.;
	%end;
run;
%mend doit;
%doit;

/* with loop automatically over all columns */
%macro doit();
data testC;
	set test;
	array cols(*) _all_;
	%do i = 1 %to dim(cols); /* here is the problem*/
		rename A&i.=B&i.;
	%end;
run;
%mend doit;
%doit;
1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

It's trivial to add a step that reads the variable names from metadata, and generates a list of rename pairs, e.g.:

 

data have ;
  array a{*} x y Cov1-Cov90;
run;

proc sql noprint;
  select cats(name,"=",transtrn(name,'Cov','Col'))
    into :renamelist separated by " "
    from dictionary.columns
    where libname='WORK' and memname='HAVE' and name like 'Cov%'
  ;
quit ;

%Put &renamelist ;

data want ;
  set have ;
  rename &renamelist ;
run ;
The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.

View solution in original post

4 REPLIES 4
Quentin
Super User

Hi,

 

Your code doesn't work because the macro language is a preprocessor.  Macro code executes before any DATA step code executes (or even compiles).  The macro language does not know about data sets, data set variables, and arrays.  So in this line:

 

%do i = 1 %to dim(cols);

dim(cols) is just a series of 9 characters to the macro language, thus the error. 

 

Can you describe a bit more of your real problem?  Do you really have only one list of variable to rename, with numeric suffixes (A1-A3) or do you have other variables as well? 

 

One approach to this is to build a macro variable that has the list of variables to be renamed.  And you can use the macro language to loop over that list.

 

For you current example, you don't actually need a macro, as you can do:

 

data testC;
  set test (rename=(A1-A3=B1-B3));
run;
The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
SamuelKnapp
Calcite | Level 5

Thanks for your quick answer.
The actual problem is to rename Cov1-Cov90 (output lsmeans) into Col1-Col90 (for use as coefficent matrix in proc mixed). As I need to run it several times, I don't want to specify the number of columns by hand, and it differs between the datasets.
I found this other post, where it was possible in a macro, but also by specifying the number of columns by hand (like the first approach):
https://communities.sas.com/t5/SAS-Enterprise-Guide/Rename-variables-using-a-loop-data-step/td-p/337...
If there is any replace method, all I need is to replace "Cov" by "Col".

And yes, there are also other variables in the dataset, but my idea was to split these variables off, change their names and merge it again...
I'm a bit surprised that this seems to be so difficult, as in R it's one line and done...
Thanks again

Quentin
Super User

It's trivial to add a step that reads the variable names from metadata, and generates a list of rename pairs, e.g.:

 

data have ;
  array a{*} x y Cov1-Cov90;
run;

proc sql noprint;
  select cats(name,"=",transtrn(name,'Cov','Col'))
    into :renamelist separated by " "
    from dictionary.columns
    where libname='WORK' and memname='HAVE' and name like 'Cov%'
  ;
quit ;

%Put &renamelist ;

data want ;
  set have ;
  rename &renamelist ;
run ;
The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
RichardDeVen
Barite | Level 11

Macro generates the source code that is submitted.

A running DATA step can't interact with macro and modify it's own running source code.

 

You can rely on knowing your variables and use `numbered range lists` to rename the variables

data have;
  array x x1-x10;
run;

data want;
  set have;
  rename x1-x10=y1-y10;  * numbered range list;
run;

or use a step to access to variable names (part of a data set's metadata) and write the rename statement.

 

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
  • 4 replies
  • 6771 views
  • 1 like
  • 3 in conversation