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 ;
BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

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;
BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
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 ;
BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
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-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 6036 views
  • 1 like
  • 3 in conversation