Search code examples
sassgplot

How to shift side-by-side bars in Proc SGPLOT for Time Data? discreteoffset doesn't work with (type=time) option


I am currently trying to create a side-by-side dual axis bar chart in proc sgplot for the data which is based on dates. I am currently stuck at last thing, where I am not able to shift the bars using discreteoffset option on vbar, because I am using Type=time on xaxis. If I comment this, then the bars are shifted but then the xaxis tick values look clumsy. So I wonder if there is any other option that can move the bars for Date/time Data? Following is my SAS code.

data input;
input people visits outcome date date9.;
datalines;
41 448 210 1-Jan-18
43 499 207 1-Feb-18
45 544 221 1-Mar-18
49 564 239 1-Apr-18
39 575 236 1-May-18
37 549 210 1-Jun-18
51 602 263 1-Jul-18
32 586 208 1-Aug-18
52 557 225 1-Sep-18
41 534 227 1-Oct-18
48 499 217 1-Nov-18
44 514 235 1-Dec-18
31 582 281 1-Jan-19
33 545 269 1-Feb-19
38 574 259 1-Mar-19
29 564 247 1-Apr-19
29 642 274 1-May-19
28 556 216 1-Jun-19
20 531 187 1-Jul-19
31 604 226 1-Aug-19
19 513 186 1-Sep-19
24 483 185 1-Oct-19
28 401 156 1-Nov-19
18 450 158 1-Dec-19
21 418 178 1-Jan-20
28 396 149 1-Feb-20
43 488 177 1-Mar-20
33 539 205 1-Apr-20
57 631 244 1-May-20
54 695 291 1-Jun-20
58 732 309 1-Jul-20
62 681 301 1-Aug-20
42 654 291 1-Sep-20
57 749 365 1-Oct-20
60 627 249 1-Nov-20
56 623 244 1-Dec-20
54 712 298 1-Jan-21
62 655 262 1-Feb-21
;
run;

proc sgplot data=input;
  format date monyy7.;
  styleattrs datacolors=(Red DarkBlue) datacontrastcolors=(black black) datalinepatterns=(solid);
  vbar date / response=visits discreteoffset=-0.17 barwidth=0.3; 
  vbar date / response=outcome discreteoffset=0.17 barwidth=0.3;
  vline date / response=people y2axis lineattrs=(color=black thickness=3);
  xaxis display=(nolabel) /*fitpolicy=rotate valuesrotate=vertical*/ type=time /*interval=month*/;
  yaxis grid label='Label1' values=(0 to 800 by 100);
  y2axis label='Label2' values=(0 to 70 by 10);
  keylegend / title="";
run;

Output I am getting: Output I am getting

Output I want: (With shifted bars, but it is changing dates) Output I Want

Appreciate any help! Thank you.


Solution

  • Reshape the data with transpose so the variables wanted side by side become categorical, i.e. name value pairs. The name can be used in vbar as the group= with groupdisplay=cluster.

    Note: The xaxis type=time appears to perform special checks based on the format of the vbar variable, and will rendered a pretty two-line axis label when that format is date9. I've never seen this discussed in the documentation.

    Example:

    Uses name= in the plotting statements so the keylegend can look prettier.

    proc transpose data=input out=plot;
      by rowid date;
      copy people;
      var visits outcome;
    run;
    
    proc sgplot data=plot;
      vbar date / response=col1 group=_name_ groupdisplay=cluster name='relatedcounts';
      vline date / response=people group=_name_ y2axis lineattrs=(color=black thickness=3) name='people';
    
      xaxis 
        type = time
        interval = month
      ;
    
      format date date9.;
    
      yaxis grid label='Related counts' values=(0 to 800 by 100);
      y2axis label='# People' values=(0 to 70 by 10);
    
      keylegend 'relatedcounts' / title="";
    run;
    

    Will produce

    enter image description here