Here is some sample code that represents a problem I'm having at work. I have SAS 9.4 and SAS Enterprise Guide 6.1 (64 bit).
If I run the code below in SAS 9.4, it runs perfectly.
If I run the code in SAS EG, it generates warnings and errors because SAS EG won't recognize a variable that has the name "Label". Of course I would not choose to give the name "Label" to a variable, but Proc Means with StackODS output will... has anyone seen this happen before and is there a work-around?
data work.meanstest;
infile datalines dlm=',';
length Item $20 Cost 8 Price 8 Profit 8;
input Item Cost Price Profit;
Label Cost='How much item costs to produce'
Price='How much we charge customer'
Profit='Profit Margin';
datalines;
Cookie,3,8,5
Cake,8,20,12
Praline,3,12,9
Toast,1,5,4
Bear Claw,2,7,5
;
run;
proc means data=work.meanstest stackods n sum mean;
var _numeric_;
ods output summary=work.stackodsmeans;
run;
proc print data=work.stackodsmeans label;
label label='SAS EG will not recognize a variable that is named Label';
run;
data work.droptest;
set work.stackodsmeans (drop=Label);
run;
proc print data=work.droptest;
run;
I'm not able to test from where I am, but did anyone try submitting this in EG ahead of the program:
options validvarname=v7;
That's the default value in Base SAS, but =ANY is the default in EG, and that can have an affect on variable name processing.
Update: this was a bug in SAS ODS prior to SAS 9.4 Maint 5. The workaround is to use VALIDVARNAME=V7, at least during the creation of the STACKODS output.
options validvarname=v7;
proc means data=work.meanstest stackods n sum mean;
var _numeric_;
ods output summary=work.stackodsmeans;
run;
options validvarname=any;
This behavior is fixed in SAS 9.4 Maint 5.
A workaround: You should be able to rename a variable on the fly. For example:
ods output summary=work.stackodsmeans (rename=(label=varlabel));
@Astounding wrote:
A workaround: You should be able to rename a variable on the fly. For example:
ods output summary=work.stackodsmeans (rename=(label=varlabel));
That doesn't work because it can't find the variable :S
l'll confirm this on SAS 9.4 and EG 7.1
This DOES NOT occur on SAS BASE 9.4 (ie no EG).
EG LOG:
24 data meanstest;
25 infile cards dlm=',';
26 length Item $20 Cost Price Profit 8;
27 input Item cost Price Profit;
28 label cost='How much item costs to produce'
29 Price='How much customer pays'
30 Profit = 'Profit Margin';
31 cards;
NOTE: The data set WORK.MEANSTEST has 5 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
37 ;
38 run;
39
40 proc means data=meanstest stackods n sum mean;
41 var _numeric_;
42 ods output summary=want;
43 run;
NOTE: The data set WORK.WANT has 3 observations and 5 variables.
NOTE: There were 5 observations read from the data set WORK.MEANSTEST.
NOTE: PROCEDURE MEANS used (Total process time):
real time 0.06 seconds
cpu time 0.03 seconds
44
45 proc contents data=want;
2 The SAS System 14:37 Monday, August 29, 2016
46 run;
NOTE: PROCEDURE CONTENTS used (Total process time):
real time 0.06 seconds
cpu time 0.01 seconds
47
48 proc print data=want label;
49 label label='Stupid vriable with issues';
WARNING: Variable LABEL not found in data set WORK.WANT.
50 run;
NOTE: There were 3 observations read from the data set WORK.WANT.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds
Program:
data meanstest;
infile cards dlm=',';
length Item $20 Cost Price Profit 8;
input Item cost Price Profit;
label cost='How much item costs to produce'
Price='How much customer pays'
Profit = 'Profit Margin';
cards;
Cookie, 3, 8,5
Cake, 8, 20,12
Praline,3,12,9
Toast,1,5,4
Bear Claw,2,7,5
;
run;
proc means data=meanstest stackods n sum mean;
var _numeric_;
ods output summary=want;
run;
proc contents data=want;
run;
proc print data=want label;
label label='Stupid variable with issues';
run;
Works for me in EG.
I can't see that EG has any involvement...all it does is pass the code to SAS.
Are you SURE it's not working?
Tom
@TomKari wrote:
Works for me in EG.
I can't see that EG has any involvement...all it does is pass the code to SAS.
Are you SURE it's not working?
Tom
Yes
data meanstest;
infile cards dlm=',';
length Item $20 Cost Price Profit 8;
input Item cost Price Profit;
label cost='How much item costs to produce'
Price='How much customer pays'
Profit = 'Profit Margin';
cards;
Cookie, 3, 8,5
Cake, 8, 20,12
Praline,3,12,9
Toast,1,5,4
Bear Claw,2,7,5
;
run;
proc means data=meanstest stackods n sum mean;
var _numeric_;
ods output summary=want(rename=label=new_var);
run;
proc contents data=want;
run;
proc print data=want label;
label label='Stupid variable with issues';
run;
40 proc means data=meanstest stackods n sum mean;
41 var _numeric_;
42 ods output summary=want(rename=label=new_var);
43 run;
WARNING: The variable label in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: The data set WORK.WANT has 3 observations and 5 variables.
NOTE: There were 5 observations read from the data set WORK.MEANSTEST.
NOTE: PROCEDURE MEANS used (Total process time):
real time 0.10 seconds
cpu time 0.01 seconds
44
45 proc contents data=want;
46 run;
2 The SAS System 14:48 Monday, August 29, 2016
NOTE: PROCEDURE CONTENTS used (Total process time):
real time 0.07 seconds
cpu time 0.00 seconds
47
48 proc print data=want label;
49 label label='Stupid variable with issues';
WARNING: Variable LABEL not found in data set WORK.WANT.
50 run;
Reeza,
The printed report from PROC CONTENTS sure looks like it is creating something called "Label". But the program definitely doesn't recognize that name.
Are you able to route the results of PROC CONTENTS to an output data set to check that the variable name "Label" doesn't contain some unprintable characters?
There may be workarounds, but the code works perfectly in Base 9.4, ie no EG.
I tried the literal option as well and that didn't work: "Label"n.
Here's the output from a print with $HEX16 format.
|
|
Yes, I also had no trouble with Base 9.4 (no EG). But your results pinpoint the problem.
Look at the hex code for the first line, where the variable name is "Label". It is ending with hex nulls (00), not hex blanks (20). That's definitely a bug, but it's not clear what the workaround would be. Perhaps worth trying:
data _null_;
call symputx('Labelvar', '4C6162656C000000'x);
run;
Then later:
ods output summary=work.stackodsmeans (rename=(&labelvar=new_name));
No go 😞
I also tried with the name literal option
"&labelvar"n
I'm not able to test from where I am, but did anyone try submitting this in EG ahead of the program:
options validvarname=v7;
That's the default value in Base SAS, but =ANY is the default in EG, and that can have an affect on variable name processing.
Update: this was a bug in SAS ODS prior to SAS 9.4 Maint 5. The workaround is to use VALIDVARNAME=V7, at least during the creation of the STACKODS output.
options validvarname=v7;
proc means data=work.meanstest stackods n sum mean;
var _numeric_;
ods output summary=work.stackodsmeans;
run;
options validvarname=any;
This behavior is fixed in SAS 9.4 Maint 5.
That does fix the problem in SAS EG. However, it should be noted that using validvarname=v7 will not allow name literals. I will likely tag this as a solution, but note that if I use this solution at work, with real data, I'll have to add extra code to rename variables that took advantage of =ANY. This is because of the lame data I'm dealing with - not SAS' fault but I do think the =ANY option should live up to its name.
If anyone else finds other solutions let us know.
Why would you have to rename them?
SAS will automatically add the _ to replace spaces and invalid characters but the labels will be the correct values.
Making sure your code leverages labels correctly will help avoid having to do this.
Though you may have to make code changes.
Although this is a valid workaround, its not what I'd expect as default behaviour from a SAS output dataset.
@Reeza wrote:Why would you have to rename them?
SAS will automatically add the _ to replace spaces and invalid characters but the labels will be the correct values.
The data set that I'm using for Proc Means StackODS is created through SAS EG and Proc Transpose, and some of the values in the transposed column become variables with name literals due to spaces. The name literals will work with =ANY but not =V7. Proc Print and Proc Means won't even read a data set with name literal vars if =V7 is turned on. In fact, you can't even view a data set in EG with =V7 if there are name literals. I get the error: "The open data operation failed...X is not a valid SAS name". I think you're right that I can get around this by only turning on that option when necessary, or perhaps I can get Proc Transpose to avoid using literals. But that would be a topic for a different post. Thanks for all your research!
Nice sleuthing @Reeza and @Astounding! I've entered a bug for tracking with SAS R&D. In the meantime, the workaround is to use VALIDVARNAME=V7, at least during the creation of the STACKODS output.
options validvarname=v7;
proc means data=work.meanstest stackods n sum mean;
var _numeric_;
ods output summary=work.stackodsmeans;
run;
options validvarname=any;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.
Find more tutorials on the SAS Users YouTube channel.