BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
xxformat_com
Barite | Level 11

Hi,

 

I was wondering why the style/merge does not provide the same result when style(calldef) is activated.

Is it a bug or is there another reason behind this result?

proc report data=sashelp.class;* style(calldef)=[foreground=white]; 
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style/merge'  ,'style=[foreground=red]');
    endcomp;
run;

 

Thanks

 

ps. as requested I had the picture when * style(calldef)=[foreground=white];  is activated

with_calldef.JPG

1 ACCEPTED SOLUTION

Accepted Solutions
xxformat_com
Barite | Level 11

Hi,

After further investigations, here are my reasoning. Do you agree?

 

Part 1 - without style(calldef)

 

Example 1: using 'style' in the second argument of compute age block.

 

 

proc report data=sashelp.class;
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[foreground=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_1.JPG

 

To start with foreground=lightblue when gender=M.

Then,

  • when gender='M' and age=12 then the foreground is changed to red (John is now in red)
  • when gender ne 'M' and age=12 then the foreground which was not yet defined is set to red.

 

Example 2: using 'style/merge' in the second argument of the compute age block.

 

 

proc report data=sashelp.class;
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[foreground=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style/merge'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_2.JPG

 

 

To start with foreground=lightblue when gender=M.

Then,

  • when gender='M' and age=12 then foreground remains lightblue (John is still in lightblue)
  • when gender ne 'M' and age=12 then the foreground which was not yet defined is set to red.

 

From these extra two examples, we understand that

- rule 1: for a given cell, the value of a given option is replaced when 'style' (or 'style/replace') is used

- rule 2: for a given cell, the value of the already defined option is not changed when 'style/merge' is used

These conclusions don't apply to style(calldef).

 

 

Example 3: using a mix of background= and foreground= as well as 'style'

 

What we didn't see in example 1, was that 'style' does not just reset the given option, but the whole cell.

 

proc report data=sashelp.class;
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_4.JPG

In this example we see that John who had a light blue background to start with has now no background and a red foreground color.

 

 

Example 4: using a mix of background= and foreground= as well as 'style/merge'

 

proc report data=sashelp.class;
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style/merge'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_5.JPG

When using 'style/merge', only options which were not set for a given value are added.

For this reason John keeps his lightblue background and get now a red foreground.

 

From these extra two examples, we understand that

- rule 1(updated): for a given cell, the value of all the options is replaced when 'style' (or 'style/replace') is used

- rule 2 (updated): for a given cell, the value of the already defined options is not changed when 'style/merge' is used

Those conclusions don't apply to style(calldef)

 

Part 2 - with style(calldef)

 

Example 5: using style(calldef) and 'style' 

 

proc report data=sashelp.class style(calldef)=[foreground=white]; 
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;
run;

xxformat_3.JPG

 

style(calldef) only applies to values defined by call define routines.

For this reason, Alice is written in black and not in white.

Even if 'style' is used, the white foreground is kept (not reset to black).

 

Example 6: using style(calldef)

 

 

proc report data=sashelp.class style(calldef)=[foreground=white]; 
columns name sex age height weight ;
define name--weight / display;

compute sex;
*if sex='M' then call define ('name' ,'style','style=[foreground=lightblue]');
if sex='M' then call define ('name' ,'style/merge','style=[foreground=lightblue]');
endcomp;
run;

xxformat_4.JPG

Here foreground is used in both style(calldef) and call define routine.

The value given in call define has priority, even if 'style/merge' is used. That's the tricky part!

 

 

 

Example 7: the original example in this post series

 

proc report data=sashelp.class style(calldef)=[foreground=white]; 
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style/merge'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_7.JPG

 

Example 5 explains us why we have white foreground on lightblue background.

A background and a foreground is already defined when gender='M'

So, given that 'style/merge' is used in the compute age block, only females where age=12 get a red foreground.

 

Note: Ballardw comment on the impact of the variables order in the column statement is an additional extra point to keep in mind. Here my compute blocks follow the same order as the one given in the column statement.

View solution in original post

9 REPLIES 9
Cynthia_sas
SAS Super FREQ

Hi:

  That's odd. The code you posted worked for me. I limited the rows to ages 12 and 13 to make for a better screen shot. In my output, all the males have a blue background and the rows where age is 12 have a red foreground color:

Cynthia_sas_0-1618186141832.png

Note how the rows for Jane and Louise have a red foreground color, but NOT a blue background color which I expect because they are 12 and they are female. On the other hand, all the rows for males do have a blue background color and the rows for James, John and Robert -- all 12 year old males have a blue background and a red foreground. I added the title to show my version of SAS.

  I don't have any other versions of SAS to test with, so you might want to open a track with Tech Support.

Cynthia

xxformat_com
Barite | Level 11

Hi Cynthia,
The code works for me too for as long as style(calldef) is not used.
Have you tested it when style(calldef) is activated in proc report statement?
Best Regards

 

ps.

Current version: 9.04.01M5P091317
Operating System: WX64_WKS.

 

ballardw
Super User

I strongly suggest that you explicitly state what values are appearing in the manner that you do not expect. By NAME and AGE.

 

 

Note that the order of the variables SEX and AGE on the column statement changes the result.

xxformat_com
Barite | Level 11
Thanks. I've now added the unexpected result in the main post.
Cynthia_sas
SAS Super FREQ

Hi:
I don't understand the purpose of the foreground=white on the CALLDEF override on the PROC REPORT statement. What were you trying to achieve when putting the override in the PROC REPORT statement? When you change the foreground to white, which would cause it to match the background? If you want to change the foreground to white when the background is blue, that would be better to do in the COMPUTE block where you're changing that background. I think you're running into a timing issue with PROC REPORT and the style overrides. I think in the long run you'd be better off NOT using the style override in the PROC REPORT statement and just delaying the compute block as late as possible by doing it on the last variable on the report row -- that way, after all the items are place on the report row, PROC REPORT only has to go back once and fiddle with the style override for the NAME cell. I'll see if I can come up with something that allows you to maintain your original order. I think with a revised IF in a COMPUTE block for WEIGHT, it can work and you won't need to use STYLE/MERGE.
Cynthia

 

Well, I could make it work with the override in the PROC REPORT statement and still maintain the original order of variables. I prefer the alternative example, because in the long run, I think it will be easier to maintain.

Cynthia_sas_0-1618245724667.png

 

xxformat_com
Barite | Level 11

Indeed, changing the order in the column statement affect the result. I didn't notice that.

But do you understand why, given style/merge is used?

 

 

Unexpected result

My code before

 

proc report data=sashelp.class style(calldef)=[foreground=white]; 
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style/merge'  ,'style=[foreground=red]');
    endcomp;
run;

result1.JPG

 

Expected result

Putting age before sex (and just for consistency, putting compute age... style, before compute sex style/merge

 

proc report data=sashelp.class style(calldef)=[foreground=white]; 
    columns name  age sex height weight ; 
    define name--weight / display;
    
    compute age;
        if age=12 then call define ('name' ,'style'  ,'style=[foreground=red]');
    endcomp;
    
    compute sex;
        if sex='M' then call define ('name' ,'style/merge','style=[background=lightblue]');
    endcomp;
run;

result2.JPG

 

Using style/merge in both compute statements would not change the result.

Ksharp
Super User
proc report data=sashelp.class nowd; 
    columns name  age sex height weight ; 
    define name--weight / display;
    
    compute sex;
	    if sex='M' then do;
              call define ('name' ,'style'  ,'style=[background=lightblue foreground=white ]'); 
			  if age=12  then call define ('name' ,'style','style=[background=lightblue  foreground=red]');
		end;
		else   if age=12  then call define ('name' ,'style','style=[foreground=red]');

    endcomp;
run;
ballardw
Super User

Still haven't seen an explicit list of which values are "misbehaving" in terms of what you expect or want.

 

As a minimum you have two overrides going on, the Style(calldef) and then the compute blocks. Order of application is likely the issue between "conflicting" overrides. I don't know if there is anything in the documentation of which will "win" when there is a conflict. Generally I expect the lowest granularity override to appear, i.e. the compute block version over one set for the procedure. But interactions?? Which is why I have asked for the specific values that you are concerned about. Yes the values change. But which ones do you want to appear how has not been answered.

xxformat_com
Barite | Level 11

Hi,

After further investigations, here are my reasoning. Do you agree?

 

Part 1 - without style(calldef)

 

Example 1: using 'style' in the second argument of compute age block.

 

 

proc report data=sashelp.class;
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[foreground=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_1.JPG

 

To start with foreground=lightblue when gender=M.

Then,

  • when gender='M' and age=12 then the foreground is changed to red (John is now in red)
  • when gender ne 'M' and age=12 then the foreground which was not yet defined is set to red.

 

Example 2: using 'style/merge' in the second argument of the compute age block.

 

 

proc report data=sashelp.class;
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[foreground=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style/merge'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_2.JPG

 

 

To start with foreground=lightblue when gender=M.

Then,

  • when gender='M' and age=12 then foreground remains lightblue (John is still in lightblue)
  • when gender ne 'M' and age=12 then the foreground which was not yet defined is set to red.

 

From these extra two examples, we understand that

- rule 1: for a given cell, the value of a given option is replaced when 'style' (or 'style/replace') is used

- rule 2: for a given cell, the value of the already defined option is not changed when 'style/merge' is used

These conclusions don't apply to style(calldef).

 

 

Example 3: using a mix of background= and foreground= as well as 'style'

 

What we didn't see in example 1, was that 'style' does not just reset the given option, but the whole cell.

 

proc report data=sashelp.class;
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_4.JPG

In this example we see that John who had a light blue background to start with has now no background and a red foreground color.

 

 

Example 4: using a mix of background= and foreground= as well as 'style/merge'

 

proc report data=sashelp.class;
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style/merge'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_5.JPG

When using 'style/merge', only options which were not set for a given value are added.

For this reason John keeps his lightblue background and get now a red foreground.

 

From these extra two examples, we understand that

- rule 1(updated): for a given cell, the value of all the options is replaced when 'style' (or 'style/replace') is used

- rule 2 (updated): for a given cell, the value of the already defined options is not changed when 'style/merge' is used

Those conclusions don't apply to style(calldef)

 

Part 2 - with style(calldef)

 

Example 5: using style(calldef) and 'style' 

 

proc report data=sashelp.class style(calldef)=[foreground=white]; 
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;
run;

xxformat_3.JPG

 

style(calldef) only applies to values defined by call define routines.

For this reason, Alice is written in black and not in white.

Even if 'style' is used, the white foreground is kept (not reset to black).

 

Example 6: using style(calldef)

 

 

proc report data=sashelp.class style(calldef)=[foreground=white]; 
columns name sex age height weight ;
define name--weight / display;

compute sex;
*if sex='M' then call define ('name' ,'style','style=[foreground=lightblue]');
if sex='M' then call define ('name' ,'style/merge','style=[foreground=lightblue]');
endcomp;
run;

xxformat_4.JPG

Here foreground is used in both style(calldef) and call define routine.

The value given in call define has priority, even if 'style/merge' is used. That's the tricky part!

 

 

 

Example 7: the original example in this post series

 

proc report data=sashelp.class style(calldef)=[foreground=white]; 
    columns name sex age height weight ; 
    define name--weight / display;
    
    compute sex;
        if sex='M' then call define ('name' ,'style','style=[background=lightblue]');
    endcomp;

    compute age;
        if age=12 then call define ('name' ,'style/merge'  ,'style=[foreground=red]');
    endcomp;
run;

xxformat_7.JPG

 

Example 5 explains us why we have white foreground on lightblue background.

A background and a foreground is already defined when gender='M'

So, given that 'style/merge' is used in the compute age block, only females where age=12 get a red foreground.

 

Note: Ballardw comment on the impact of the variables order in the column statement is an additional extra point to keep in mind. Here my compute blocks follow the same order as the one given in the column statement.

SAS Innovate 2025: Call for Content

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!

Submit your idea!

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
  • 9 replies
  • 1214 views
  • 0 likes
  • 4 in conversation