Sometimes, it can be convenient to disply both variable name and variable label in the header of a table.
I can automate the following proc report using a data _null_.
But I was wondering on whether there is a smarter way to get the result.
Data
data class;
label name = 'Name Label'
sex = 'Sex Label'
age = 'Age Label'
height = 'Height Label'
weight = 'Weight Label';
set sashelp.class;
run;
proc report
proc report data=class;
column ('Name Label' name)
('Sex Label' sex)
('Age Label' age)
('Height Label' height)
('Weight Label' weight);
attrib _all_ label=" ";
run;
@xxformat_com wrote:
Sometimes, it can be convenient to disply both variable name and variable label in the header of a table.
I can automate the following proc report using a data _null_.
But I was wondering on whether there is a smarter way to get the result.
Smarter perhaps — but initially more work: you can read the variable names and labels from either PROC CONTENTS output or from the dictionary tables, and then create a macro that essentially creates the LABEL statement that you have.
I will get you started using data set SASHELP.GAS
proc sql noprint;
select name, coalesce(label,name) into :names separated by ' ',:labels separated by '~'
from dictionary.columns
where libname='SASHELP' and memname='GAS'
order by varnum;
quit;
%put &=names;
%put &=labels;
Now you have macro variables containing the variable names and the variable labels. From there, you would have to create macro code to generate the LABEL statement you need.
If you need the label to display the name then include the name in the label and just use the LABEL as the header.
data class;
set sashelp.class;
label name = 'Name Label (NAME)'
sex = 'Sex Label (SEX)'
age = 'Age Label (AGE)'
height = 'Height Label (HEIGHT)'
weight = 'Weight Label (WEIGHT)'
;
run;
Now the down stream code does not need anything special.
proc report data=class;
run;
You can automate the addition of the name to the label.
data class;
set sashelp.class;
label name = 'Name Label'
sex = 'Sex Label'
age = 'Age Label'
height = 'Height Label'
weight = 'Weight Label'
;
run;
proc transpose data=class(obs=0) out=names;
var _all_;
run;
filename code temp;
data names;
length varnum 8 _name_ $32 _label_ $256 ;
set names ;
varnum+1;
file code ;
_label_=coalescec(_label_,_name_);
_label_=catx(' ',_label_,cats('(',upcase(_name_),')'));
put 'label ' _name_ '=' _label_ :$quote. ';';
run;
Now either run the generated LABEL statements in a DATA step or PROC DATASETS step to change the attached labels.
Or include the LABEL statements into the PROC step that is using the data.
1206 proc report data=class ; 1207 %include code / source2; NOTE: %INCLUDE (level 1) file CODE is file ...\#LN00063. 1208 +label Name ="Name Label (NAME)" ; 1209 +label Sex ="Sex Label (SEX)" ; 1210 +label Age ="Age Label (AGE)" ; 1211 +label Height ="Height Label (HEIGHT)" ; 1212 +label Weight ="Weight Label (WEIGHT)" ; NOTE: %INCLUDE (level 1) ending. 1213 run;
You could make a macro variable to contain that statement.
data class;
set sashelp.class;
label name = 'Name Label'
sex = 'Sex Label'
age = 'Age Label'
height = 'Height Label'
weight = 'Weight Label';
run;
proc sql noprint;
select catx(' ','("',label,'"',name,')') into :header separated by ' '
from dictionary.columns
where libname='WORK' and memname='CLASS';
quit;
proc report data=class nowd;
column &header ;
attrib _all_ label=" ";
run;
Reading the other replies, I now wonder if your question is: how to do this so that the variable name is always followed by the word Label; or if you want something more general where there are actual labels that are different than the variable name.
Please clarify this.
@xxformat_com wrote:
You're right. My original question was not about adding the variable name in brackets after the variable. But it is another interesting approach for providing both variable label and name, I hadn't thought about. I take it as a nice tip as it makes the code light.
My actual question was to get one row for the variable label and another one for the variable name without having to automate (i.e. without data _null_ or without macro language).
I have to say that you didn't answer my question. And so nothing has been cleared up. Your original code took the variable name and appended the word "Label" and this is now the label you want to use. Is that all you are asking to do, append the word "Label" after the variable name, or do you want to use the actual variable labels? For example, in SASHELP.GAS where three of the variables in the data set have a label attached to it, the variable CPRATIO has label "Compression Ratio", and so do you want "Compression Ratio" to appear in your PROC REPORT output or do you want "CPRATIO Label" to appear in your PROC REPORT output? Please make this clear.
You want an answer without macros and without DATA _NULL_ — why? Why eliminate valid tools to get the job done?
I have the impression that I answered your question. I'm not sure what it is not clear in my question. There is a picture showing exactly what I'm looking for: one row for variable label and one for variable name.
I've added in the example label just because it was an example for people to quickly test there code.
The goal is not to get the expected output. I'm able to get it with data _null_ or macro; Those solutions overcomplicate the program.
I was looking for a smarter approach, if any exist. It could be that there is no possibility.
I was just asking if someone would be aware of something I'm not aware of. SAS has so many features. It's easy to missout one (many actually).
Ok, we're not communicating, and I'll let other people who apparently do understand you help.
As others proposed I believe the most generic solution that will work with any procedure creating a report would be to add the column name to the label.
If you don't want to change the labels permanently on the source table then at least some of the PROC's allow for a label statement.
Based on @Ksharp's code below a sample how this could work.
data class;
set sashelp.class;
label name = 'Name Label'
sex = 'Sex Label'
age = 'Age Label'
height = 'Height Label'
weight = 'Weight Label';
run;
proc sql noprint;
select catt(name,"='",label," (",name,")'") into :label separated by ' '
from dictionary.columns
where libname='WORK' and memname='CLASS';
quit;
%put &label;
proc report data=class nowd;
column _all_ ;
label &label;
run;
proc print data=class label;
label &label;
run;
This solution does not answer exactly my question but allows at least to have two lines in a row.
data class;
label name = 'Name Label*Name'
sex = 'Sex Label*Sex'
age = 'Age Label*Age'
height = 'Height Label*Height'
weight = 'Weight Label*Weight';
set sashelp.class;
run;
proc report data=class split='*';
run;
I'm still investing.
@xxformat_com If you want the exact layout as per your sample then use the code @Ksharp proposed.
Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.
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.
Ready to level-up your skills? Choose your own adventure.