Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rename variables without using their original names?

Tags:

sas

I have a data set that I am uploading to sas. There are always 4 variables in the exact same order. The problem is sometimes the variables could have slightly different names.

For example the first variable user . The next day i get the same dataset, it might be userid . . . So I cannot use rename(user=my_user)

Is there any way i could refer to the variable by their order . . something like this

rename(var_order_1=my_user) ;

rename(var_order_3=my_inc) ;

rename _ALL_=x1-x4 ;

like image 668
Buras Avatar asked Feb 13 '23 13:02

Buras


2 Answers

There are a few ways to do this. One is to determine the variable names from PROC CONTENTS or dictionary.columns and generate rename statements.

data have;
input x1-x4;
datalines;
1 2 3 4
5 6 7 8
;;;;
run;


%macro rename(var=,newvar=); 
rename &var.=&newvar.;
%mend rename;

data my_vars;   *the list of your new variable names, and their variable number;
length varname $10;
input varnum varname $;
datalines;
1 FirstVar
2 SecondVar
3 ThirdVar
4 FourthVar
;;;;
run;

proc sql;     *Create a list of macro calls to the rename macro from joining dictionary.columns with your data. ;
              * Dictionary.columns is like proc contents.;
select cats('%rename(var=',name,',newvar=',varname,')')
  into :renamelist separated by ' '
  from dictionary.columns C, my_vars M
  where C.memname='HAVE' and C.libname='WORK'
    and C.varnum=M.varnum;
quit;

proc datasets;
modify have;
&renamelist;  *use the calls;
quit;

Another is to put/input the data using the input stream and the _INFILE_ automatic variable (that references the current line in the input stream). Here's an example. You would of course keep only the new variables if you wanted.

data have;
input x1-x4;
datalines;
1 2 3 4
5 6 7 8
;;;;
run;

data want;
set have;
infile datalines truncover;   *or it will go to next line and EOF prematurely;
input @1 @@;                  *Reinitialize to the start of the line or it will eventually EOF early;
_infile_=catx(' ',of _all_);  *put to input stream as space delimited - if your data has spaces you need something else;
input y1-y4 @@;               *input as space delimited;
put _all_;                    *just checking our work, for debugging;
datalines;                    *dummy datalines (could use a dummy filename as well);

;;;;
run;
like image 67
Joe Avatar answered May 10 '23 07:05

Joe


Here is another approach using the dictionary tables..

data have;
   format var1-var4 $1.;
   call missing (of _all_);
run;
proc sql noprint;
select name into: namelist separated by ' '  /* create macro var */
   from dictionary.columns
   where libname='WORK' and memname='HAVE' /* uppercase */
   order by varnum; /* should be ordered by this anyway */

%macro create_rename(invar=);
%do x=1 %to %sysfunc(countw(&namelist,%str( )));
   /* OLDVAR = NEWVARx */
   %scan(&namelist,&x) = NEWVAR&x
%end;
%mend;

data want ;
   set have (rename=(%create_rename(invar=&namelist)));
   put _all_;
run;

gives:

NEWVAR1=  NEWVAR2=  NEWVAR3=  NEWVAR4=
like image 28
Allan Bowe Avatar answered May 10 '23 09:05

Allan Bowe