BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
RAVI2000
Lapis Lazuli | Level 10

Hello everyone,

 

I have a sas dataset that has values like below.

 

RAVI2000_0-1669756879903.png

The variable name "LSIDEM01_Listing_of_Subject_Dem" is very big. I want the observation 1 values to be variable names for all the B, C, D, E, F, G, H....

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Transpose the first row.

proc transpose data=HAVE(obs=1) out=names name=oldname;
  var _all_;
run;

Now convert the gibberish into something that could be used as a variable name, you can use the original gibberish as the label.

data names;
  length varnum 8 oldname name $32 label $256 ;
  set names;
  varnum+1;
  label=col1;
* Replace adjacent non-valid characters with single underscore ;
  name=translate(trim(prxchange('s/([^a-zA-Z0-9]+)/ /',-1,col1)),' _','_ ');
  name=prxchange('s/(^[0-9])/_$1/',1,name);  
  drop col1;
run;

Now generate code to rename the variables and attach the labels.

filename code temp;
data _null_;
  file code;
  put 'rename' ;
  do p=1 to nobs;
    set names point=p nobs=nobs;
    if upcase(name) ne upcase(oldname) then 
      put oldname '=' name 
    ;
  end;
  put ';' ;
  do p=1 to nobs;
    set names point=p;
    if label ne name then do;
      label=quote(trim(label),"'");
      put 'label ' oldname '=' label ';' ;
    end;
  end;
  stop;
run;

Now you can use the generated RENAME and LABEL statements in either a new data step.

data want;
  set have(firstobs=2);
%include code / source2;
run;

Or as part of a PROC DATASETS step.

proc dataset nolist lib=work;
modify have ;
%include code / source2;
run;
quit;

 

View solution in original post

12 REPLIES 12
Tom
Super User Tom
Super User

How was the dataset you have created?  With names like B,C,D,... it looks like you imported a spreadsheet.  So why not take a step back and create the dataset with valid names to begin with?

 

RAVI2000
Lapis Lazuli | Level 10
Thanks @Tom It was imported from excel, I didn't create it. It comes from a different team and I cannot edit it. I can only import and then do more modifications.
Tom
Super User Tom
Super User

@RAVI2000 wrote:
Thanks @Tom It was imported from excel, I didn't create it. It comes from a different team and I cannot edit it. I can only import and then do more modifications.

Your first and last sentences contradict each other.  Assuming the last one is correct and it was you that created the dataset by importing an Excel file then just change how you imported it.

proc import file='somefile.xlsx' dbms=xlsx out=want replace;
  range='$A2:';
run;

 

PaigeMiller
Diamond | Level 26

@RAVI2000 wrote:
Thanks @Tom It was imported from excel, I didn't create it. It comes from a different team and I cannot edit it. I can only import and then do more modifications.

You could ... politely ... ask them to re-do it such that the problem is fixed. To me this is the optimal solution. You're lucky @Tom has figured out how to fix this in SAS, I would not have even tried.

--
Paige Miller
RAVI2000
Lapis Lazuli | Level 10
Yes, going forward we have raised a request. That is really not a good data to work on with.
Tom
Super User Tom
Super User

Transpose the first row.

proc transpose data=HAVE(obs=1) out=names name=oldname;
  var _all_;
run;

Now convert the gibberish into something that could be used as a variable name, you can use the original gibberish as the label.

data names;
  length varnum 8 oldname name $32 label $256 ;
  set names;
  varnum+1;
  label=col1;
* Replace adjacent non-valid characters with single underscore ;
  name=translate(trim(prxchange('s/([^a-zA-Z0-9]+)/ /',-1,col1)),' _','_ ');
  name=prxchange('s/(^[0-9])/_$1/',1,name);  
  drop col1;
run;

Now generate code to rename the variables and attach the labels.

filename code temp;
data _null_;
  file code;
  put 'rename' ;
  do p=1 to nobs;
    set names point=p nobs=nobs;
    if upcase(name) ne upcase(oldname) then 
      put oldname '=' name 
    ;
  end;
  put ';' ;
  do p=1 to nobs;
    set names point=p;
    if label ne name then do;
      label=quote(trim(label),"'");
      put 'label ' oldname '=' label ';' ;
    end;
  end;
  stop;
run;

Now you can use the generated RENAME and LABEL statements in either a new data step.

data want;
  set have(firstobs=2);
%include code / source2;
run;

Or as part of a PROC DATASETS step.

proc dataset nolist lib=work;
modify have ;
%include code / source2;
run;
quit;

 

RAVI2000
Lapis Lazuli | Level 10

I have tried your code, and I work on cloud studio.

RAVI2000_0-1669759439509.png

The "filename" statement is not reading the correct temp path.

 

Tom
Super User Tom
Super User

The code has been updated to account for the missing NOBS= option and other issues.

But if you still ahve the original XLSX file you don't need it.  You can tell SAS to skip the first line when importing the file.  That will also allow SAS to discover any numeric variables that might be in the there since it no longer will treat the column headers as data.

RAVI2000
Lapis Lazuli | Level 10
What option in proc import do I specify for it? I have tried it with range and datarow options. I didn't get exact row of the data that I am looking for. This excel has the variables values in the first observation. But other sheet have the values in 4th , 5th observations.
PaigeMiller
Diamond | Level 26

Example:

 

proc import datafile="mydatafile.xlsx" out=abc dbms=excel replace;
    getnames=yes;
run;
--
Paige Miller
RAVI2000
Lapis Lazuli | Level 10
Thank you very much @Tom It really helped me alot!
Tom
Super User Tom
Super User

Use the RANGE option to specify the upper left corner and PROC IMPORT will import that.

So to skip the first row then start in A2.  To skip 4 lines start in A5.

proc import file='c:\downloads\test_range.xlsx' dbms=xlsx out=want replace;
  range='$A2:' ;
run;

If the file also includes junk below or to the right of the table then specify the full range.

proc import file='c:\downloads\test_range.xlsx' dbms=xlsx out=want replace;
  range='$A2:E18' ;
run;

 

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
  • 12 replies
  • 1636 views
  • 5 likes
  • 3 in conversation